home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / ATL / include / Atlbase.h next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  140.5 KB  |  6,275 lines

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10.  
  11. #ifndef __ATLBASE_H__
  12. #define __ATLBASE_H__
  13.  
  14. #ifndef __cplusplus
  15.     #error ATL requires C++ compilation (use a .cpp suffix)
  16. #endif
  17.  
  18. #if defined(_WIN32_WCE) && (_WIN32_WCE < 200)
  19. #error "ATL projects can only be compiled for Windows CE 2.0 or later."
  20. #endif // _WIN32_WCE
  21.  
  22. #if defined(_WIN32_WCE)
  23. #include "wceatl.h"
  24. #define WCE_DEL /##/
  25. #define WCE_INS
  26. #define WCE_FCTN(fctn) wce_##fctn
  27. #define WCE_IF(wce,base) wce
  28. #define WCE_ATL_LIBNAME                WCE_FILENAME_1(atlce,_WIN32_WCE,.lib)
  29. #define WCE_FILENAME_1(name, ver, ext) WCE_FILENAME_2(name, ver, ext)
  30. #define WCE_FILENAME_2(name, ver, ext) #name #ver #ext
  31. #else // _WIN32_WCE
  32. #define _T(x) x
  33. #define WCE_DEL
  34. #define WCE_INS /##/
  35. #define WCE_FCTN(fctn) fctn
  36. #define WCE_IF(wce,base) base
  37. #endif // _WIN32_WCE
  38. #ifndef _ATL_NO_PRAGMA_WARNINGS
  39. #pragma warning(disable: 4201) // nameless unions are part of C++
  40. #pragma warning(disable: 4127) // constant expression
  41. #pragma warning(disable: 4505) // unreferenced local function has been removed
  42. #pragma warning(disable: 4512) // can't generate assignment operator (so what?)
  43. #pragma warning(disable: 4514) // unreferenced inlines are common
  44. #pragma warning(disable: 4103) // pragma pack
  45. #pragma warning(disable: 4702) // unreachable code
  46. #pragma warning(disable: 4237) // bool
  47. #pragma warning(disable: 4710) // function couldn't be inlined
  48. #pragma warning(disable: 4355) // 'this' : used in base member initializer list
  49. #pragma warning(disable: 4097) // typedef name used as synonym for class-name
  50. #pragma warning(disable: 4786) // identifier was truncated in the debug information
  51. #endif //!_ATL_NO_PRAGMA_WARNINGS
  52.  
  53. #include <atldef.h>
  54.  
  55. #include <windows.h>
  56. #include <winnls.h>
  57. #include <ole2.h>
  58.  
  59. WCE_INS typedef GUID CATID;        // missed definition from comcat.h
  60. WCE_DEL #include <comcat.h>
  61. WCE_DEL #include <stddef.h>
  62.  
  63. #include <tchar.h>
  64. #include <malloc.h>
  65.  
  66. #ifndef _ATL_NO_DEBUG_CRT
  67. // Warning: if you define the above symbol, you will have
  68. // to provide your own definition of the ATLASSERT(x) macro
  69. // in order to compile ATL
  70.     #include <crtdbg.h>
  71. #endif
  72.  
  73. #include <olectl.h>
  74. #include <winreg.h>
  75. #include <atliface.h>
  76.  
  77. #ifdef _DEBUG
  78. WCE_DEL #include <stdio.h>
  79. #include <stdarg.h>
  80. #endif
  81.  
  82. #include <atlconv.h>
  83.  
  84. WCE_DEL #include <shlwapi.h>
  85.  
  86. #pragma pack(push, _ATL_PACKING)
  87.  
  88. #if defined(_ATL_DLL)
  89. #if defined(_WIN32_WCE)
  90.     #pragma comment(lib, WCE_ATL_LIBNAME)
  91. #else // _WIN32_WCE
  92.     #pragma comment(lib, "atl.lib")
  93. #endif // _WIN32_WCE
  94. #endif
  95. #if defined(_WIN32_WCE)
  96. namespace ATL
  97. {
  98.     HRESULT wce_OleLoadFromStream ( LPSTREAM pStm, REFIID iidInterface, LPVOID FAR* ppvObj);
  99.     HRESULT wce_OleSaveToStream ( LPPERSISTSTREAM pPStm, LPSTREAM pStm);
  100.     HRESULT wce_ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID);
  101.     HRESULT wce_CLSIDFromProgID(LPCOLESTR lpszProgID, LPCLSID pclsid);
  102.     HRESULT wce_CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
  103.     int    wce_MulDiv(int nNumber, int nNumerator, int nDenominator);
  104. } // namespace ATL
  105.  
  106. #endif // _WIN32_WCE
  107.  
  108. extern "C" const __declspec(selectany) GUID LIBID_ATLLib = {0x44EC0535,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  109. extern "C" const __declspec(selectany) CLSID CLSID_Registrar = {0x44EC053A,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  110. extern "C" const __declspec(selectany) IID IID_IRegistrar = {0x44EC053B,0x400F,0x11D0,{0x9D,0xCD,0x00,0xA0,0xC9,0x03,0x91,0xD3}};
  111. extern "C" const __declspec(selectany) IID IID_IAxWinHostWindow = {0xb6ea2050,0x48a,0x11d1,{0x82,0xb9,0x0,0xc0,0x4f,0xb9,0x94,0x2e}};
  112. extern "C" const __declspec(selectany) IID IID_IAxWinAmbientDispatch = {0xb6ea2051,0x48a,0x11d1,{0x82,0xb9,0x0,0xc0,0x4f,0xb9,0x94,0x2e}};
  113. WCE_DEL extern "C" const __declspec(selectany) IID IID_IInternalConnection = {0x72AD0770,0x6A9F,0x11d1,{0xBC,0xEC,0x00,0x60,0x08,0x8F,0x44,0x4E}};
  114. WCE_DEL extern "C" const __declspec(selectany) IID IID_IDocHostUIHandlerDispatch = {0x425B5AF0,0x65F1,0x11d1,{0x96,0x11,0x00,0x00,0xF8,0x1E,0x0D,0x0D}};
  115.  
  116. #ifndef _ATL_DLL_IMPL
  117. namespace ATL
  118. {
  119. #endif
  120.  
  121. struct _ATL_CATMAP_ENTRY
  122. {
  123.    int iType;
  124.    const CATID* pcatid;
  125. };
  126.  
  127. #define _ATL_CATMAP_ENTRY_END 0
  128. #define _ATL_CATMAP_ENTRY_IMPLEMENTED 1
  129. #define _ATL_CATMAP_ENTRY_REQUIRED 2
  130.  
  131. typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
  132. typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD dw);
  133. typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD dw);
  134. typedef LPCTSTR (WINAPI _ATL_DESCRIPTIONFUNC)();
  135. typedef const struct _ATL_CATMAP_ENTRY* (_ATL_CATMAPFUNC)();
  136. typedef void (__stdcall _ATL_TERMFUNC)(DWORD dw);
  137.  
  138. struct _ATL_TERMFUNC_ELEM
  139. {
  140.     _ATL_TERMFUNC* pFunc;
  141.     DWORD dw;
  142.     _ATL_TERMFUNC_ELEM* pNext;
  143. };
  144.  
  145. struct _ATL_OBJMAP_ENTRY
  146. {
  147.     const CLSID* pclsid;
  148.     HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  149.     _ATL_CREATORFUNC* pfnGetClassObject;
  150.     _ATL_CREATORFUNC* pfnCreateInstance;
  151.     IUnknown* pCF;
  152.     DWORD dwRegister;
  153.     _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  154.     _ATL_CATMAPFUNC* pfnGetCategoryMap;
  155. #if !defined(_WIN32_WCE)
  156.     HRESULT WINAPI RevokeClassObject()
  157.     {
  158.         return CoRevokeClassObject(dwRegister);
  159.     }
  160.     HRESULT WINAPI RegisterClassObject(DWORD dwClsContext, DWORD dwFlags)
  161.     {
  162.         IUnknown* p = NULL;
  163.         if (pfnGetClassObject == NULL)
  164.             return S_OK;
  165.         HRESULT hRes = pfnGetClassObject(pfnCreateInstance, IID_IUnknown, (LPVOID*) &p);
  166.         if (SUCCEEDED(hRes))
  167.             hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
  168.         if (p != NULL)
  169.             p->Release();
  170.         return hRes;
  171.     }
  172. #endif // _WIN32_WCE
  173. // Added in ATL 3.0
  174.     void (WINAPI *pfnObjectMain)(bool bStarting);
  175. };
  176.  
  177. struct _ATL_REGMAP_ENTRY
  178. {
  179.     LPCOLESTR     szKey;
  180.     LPCOLESTR     szData;
  181. };
  182.  
  183. struct _AtlCreateWndData
  184. {
  185.     void* m_pThis;
  186.     DWORD m_dwThreadID;
  187.     _AtlCreateWndData* m_pNext;
  188. };
  189.  
  190. struct _ATL_MODULE
  191. {
  192. // Attributes
  193. public:
  194.     UINT cbSize;
  195.     HINSTANCE m_hInst;
  196.     HINSTANCE m_hInstResource;
  197.     HINSTANCE m_hInstTypeLib;
  198.     _ATL_OBJMAP_ENTRY* m_pObjMap;
  199.     LONG m_nLockCnt;
  200.     HANDLE m_hHeap;
  201.     union
  202.     {
  203.         CRITICAL_SECTION m_csTypeInfoHolder;
  204.         CRITICAL_SECTION m_csStaticDataInit;
  205.     };
  206.     CRITICAL_SECTION m_csWindowCreate;
  207.     CRITICAL_SECTION m_csObjMap;
  208. // Original Size = 100
  209. // Stuff added in ATL 3.0
  210.     DWORD dwAtlBuildVer;
  211.     _AtlCreateWndData* m_pCreateWndList;
  212.     bool m_bDestroyHeap;
  213.     GUID* pguidVer;
  214.     DWORD m_dwHeaps;    // Number of heaps we have (-1)
  215.     HANDLE* m_phHeaps;
  216.     int m_nHeap;        // Which heap to choose from
  217.     _ATL_TERMFUNC_ELEM* m_pTermFuncs;
  218. };
  219.  
  220. const int _nAtlModuleVer1Size = 100;
  221.  
  222. //This define makes debugging asserts easier.
  223. #define _ATL_SIMPLEMAPENTRY ((_ATL_CREATORARGFUNC*)1)
  224.  
  225. struct _ATL_INTMAP_ENTRY
  226. {
  227.     const IID* piid;       // the interface id (IID)
  228.     DWORD dw;
  229.     _ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr
  230. };
  231.  
  232. /////////////////////////////////////////////////////////////////////////////
  233. // QI Support
  234.  
  235. ATLAPI AtlInternalQueryInterface(void* pThis,
  236.     const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject);
  237.  
  238. /////////////////////////////////////////////////////////////////////////////
  239. // Smart Pointer helpers
  240.  
  241. ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  242. ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid);
  243.  
  244. /////////////////////////////////////////////////////////////////////////////
  245. // Inproc Marshaling helpers
  246.  
  247. WCE_DEL ATLAPI AtlFreeMarshalStream(IStream* pStream);
  248. WCE_DEL ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream);
  249. WCE_DEL ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk);
  250.  
  251. WCE_DEL ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent);
  252.  
  253. /////////////////////////////////////////////////////////////////////////////
  254. // Connection Point Helpers
  255.  
  256. ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw);
  257. ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw);
  258.  
  259. /////////////////////////////////////////////////////////////////////////////
  260. // IDispatch Error handling
  261.  
  262. ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc,
  263.     DWORD dwHelpID, LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes,
  264.     HINSTANCE hInst);
  265.  
  266. /////////////////////////////////////////////////////////////////////////////
  267. // Module
  268.  
  269. WCE_DEL ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags);
  270. WCE_DEL ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM);
  271. ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv);
  272. ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID = NULL);
  273. ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID = NULL);
  274. ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL);
  275. ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE*pM, LPCOLESTR lpszRes,
  276.     BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg = NULL);
  277. ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);
  278. ATLAPI AtlModuleUnRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex);
  279. ATLAPI AtlModuleLoadTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib);
  280.  
  281. ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h);
  282. ATLAPI AtlModuleTerm(_ATL_MODULE* pM);
  283. ATLAPI_(DWORD) AtlGetVersion(void* pReserved);
  284. ATLAPI_(void) AtlModuleAddCreateWndData(_ATL_MODULE* pM, _AtlCreateWndData* pData, void* pObject);
  285. ATLAPI_(void*) AtlModuleExtractCreateWndData(_ATL_MODULE* pM);
  286. ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD dw);
  287.  
  288.  
  289. #ifndef _ATL_DLL_IMPL
  290. }; //namespace ATL
  291. #endif
  292.  
  293. namespace ATL
  294. {
  295.  
  296. enum atlTraceFlags
  297. {
  298.     // Application defined categories
  299.     atlTraceUser         = 0x00000001,
  300.     atlTraceUser2         = 0x00000002,
  301.     atlTraceUser3         = 0x00000004,
  302.     atlTraceUser4         = 0x00000008,
  303.     // ATL defined categories
  304.     atlTraceGeneral        = 0x00000020,
  305.     atlTraceCOM         = 0x00000040,
  306.     atlTraceQI        = 0x00000080,
  307.     atlTraceRegistrar    = 0x00000100,
  308.     atlTraceRefcount    = 0x00000200,
  309.     atlTraceWindowing    = 0x00000400,
  310.     atlTraceControls    = 0x00000800,
  311.     atlTraceHosting        = 0x00001000,
  312.     atlTraceDBClient    = 0x00002000,
  313.     atlTraceDBProvider    = 0x00004000,
  314.     atlTraceSnapin        = 0x00008000,
  315.     atlTraceNotImpl        = 0x00010000,
  316. };
  317.  
  318. #ifndef ATL_TRACE_CATEGORY
  319. #define ATL_TRACE_CATEGORY 0xFFFFFFFF
  320. #endif
  321.  
  322. #ifdef _DEBUG
  323.  
  324. #ifndef ATL_TRACE_LEVEL
  325. #define ATL_TRACE_LEVEL 0
  326. #endif
  327.  
  328. #if !defined(_WIN32_WCE)
  329. inline void _cdecl AtlTrace(LPCSTR lpszFormat, ...)
  330. {
  331.     va_list args;
  332.     va_start(args, lpszFormat);
  333.  
  334.     int nBuf;
  335.     char szBuffer[512];
  336.  
  337.     nBuf = _vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
  338.     ATLASSERT(nBuf < sizeof(szBuffer)); //Output truncated as it was > sizeof(szBuffer)
  339.  
  340.     OutputDebugStringA(szBuffer);
  341.     va_end(args);
  342. }
  343. inline void _cdecl AtlTrace2(DWORD category, UINT level, LPCSTR lpszFormat, ...)
  344. {
  345.     if (category & ATL_TRACE_CATEGORY && level <= ATL_TRACE_LEVEL)
  346.     {
  347.         va_list args;
  348.         va_start(args, lpszFormat);
  349.  
  350.         int nBuf;
  351.         char szBuffer[512];
  352.  
  353.         nBuf = _vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
  354.         ATLASSERT(nBuf < sizeof(szBuffer)); //Output truncated as it was > sizeof(szBuffer)
  355.  
  356.         OutputDebugStringA("ATL: ");
  357.         OutputDebugStringA(szBuffer);
  358.         va_end(args);
  359.     }
  360. }
  361. #endif // _WIN32_WCE
  362. #ifndef OLE2ANSI
  363. inline void _cdecl AtlTrace(LPCWSTR lpszFormat, ...)
  364. {
  365.     va_list args;
  366.     va_start(args, lpszFormat);
  367.  
  368.     int nBuf;
  369.     WCHAR szBuffer[512];
  370.  
  371. #if defined(_WIN32_WCE)
  372.     nBuf = _vstprintf(szBuffer, lpszFormat, args);
  373. #else // _WIN32_WCE
  374.     nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(WCHAR), lpszFormat, args);
  375. #endif // _WIN32_WCE
  376.     ATLASSERT(nBuf < sizeof(szBuffer));//Output truncated as it was > sizeof(szBuffer)
  377.  
  378.     OutputDebugStringW(szBuffer);
  379.     va_end(args);
  380. }
  381. inline void _cdecl AtlTrace2(DWORD category, UINT level, LPCWSTR lpszFormat, ...)
  382. {
  383.     if (category & ATL_TRACE_CATEGORY && level <= ATL_TRACE_LEVEL)
  384.     {
  385.         va_list args;
  386.         va_start(args, lpszFormat);
  387.  
  388.         int nBuf;
  389.         WCHAR szBuffer[512];
  390.  
  391. #if defined(_WIN32_WCE)
  392.         nBuf = _vstprintf(szBuffer, lpszFormat, args);
  393. #else // _WIN32_WCE
  394.         nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(WCHAR), lpszFormat, args);
  395. #endif // _WIN32_WCE
  396.         ATLASSERT(nBuf < sizeof(szBuffer));//Output truncated as it was > sizeof(szBuffer)
  397.  
  398.         OutputDebugStringW(L"ATL: ");
  399.         OutputDebugStringW(szBuffer);
  400.         va_end(args);
  401.     }
  402. }
  403. #endif //!OLE2ANSI
  404.  
  405.  
  406. #ifndef ATLTRACE
  407. #define ATLTRACE            AtlTrace
  408. #define ATLTRACE2           AtlTrace2
  409. #endif
  410. #define ATLTRACENOTIMPL(funcname)   ATLTRACE2(atlTraceNotImpl, 2, _T("ATL: %s not implemented.\n"), funcname); return E_NOTIMPL
  411. #else // !DEBUG
  412. inline void _cdecl AtlTrace(LPCSTR , ...){}
  413. inline void _cdecl AtlTrace2(DWORD, UINT, LPCSTR , ...){}
  414. #ifndef OLE2ANSI
  415. inline void _cdecl AtlTrace(LPCWSTR , ...){}
  416. inline void _cdecl AtlTrace2(DWORD, UINT, LPCWSTR , ...){}
  417. #endif //OLE2ANSI
  418. #ifndef ATLTRACE
  419. #define ATLTRACE            1 ? (void)0 : AtlTrace
  420. #define ATLTRACE2            1 ? (void)0 : AtlTrace2
  421. #endif //ATLTRACE
  422. #define ATLTRACENOTIMPL(funcname)   return E_NOTIMPL
  423. #endif //_DEBUG
  424.  
  425.  
  426.  
  427.  
  428.  
  429. /////////////////////////////////////////////////////////////////////////////
  430. // Win32 libraries
  431.  
  432. #ifndef _ATL_NO_FORCE_LIBS
  433. #if defined(_WIN32_WCE)
  434.     #pragma comment(lib, "coredll.lib")
  435.     #pragma comment(lib, "commctrl.lib")
  436.     #pragma comment(lib, "uuid.lib")
  437.     #if defined(_WIN32_WCE_EMULATION) && (_WIN32_WCE < 210) 
  438.         #pragma comment(lib, "ole32m.lib")
  439.         #pragma comment(lib, "oleautm.lib")
  440.     #else
  441.         #pragma comment(lib, "ole32.lib")
  442.         #pragma comment(lib, "oleaut32.lib")
  443.     #endif // _WIN32_WCE_EMULATION
  444.     #if (_WIN32_WCE > 200)    
  445.         #pragma comment(lib, "corelibc.lib")
  446.         #pragma comment(linker, "/nodefaultlib:libc.lib")
  447.         #pragma comment(linker, "/nodefaultlib:libcd.lib")
  448.         #pragma comment(linker, "/nodefaultlib:libcmt.lib")
  449.         #pragma comment(linker, "/nodefaultlib:libcmtd.lib")
  450.         #pragma comment(linker, "/nodefaultlib:oldnames.lib")
  451.     #else // _WIN32_WCE > 200
  452.         #if defined(_DEBUG)
  453.             #pragma comment(lib, "libcmtd.lib")
  454.             #pragma comment(linker, "/nodefaultlib:corelibc.lib")
  455.         #else
  456.             #pragma comment(lib, "libcmt.lib")
  457.             #pragma comment(linker, "/nodefaultlib:corelibc.lib")
  458.         #endif
  459.     #endif // _WIN32_WCE > 200
  460. #else                            // Win32
  461.     #pragma comment(lib, "kernel32.lib")
  462.     #pragma comment(lib, "user32.lib")
  463.     #pragma comment(lib, "olepro32.lib")
  464.     #pragma comment(lib, "advapi32.lib")
  465.     #pragma comment(lib, "ole32.lib")
  466.     #pragma comment(lib, "oleaut32.lib")
  467.     #pragma comment(lib, "uuid.lib")
  468. #endif // _WIN32_WCE
  469. #endif // _ATL_NO_FORCE_LIBS
  470.  
  471. static HRESULT AtlSetChildSite(IUnknown* punkChild, IUnknown* punkParent)
  472. {
  473.     if (punkChild == NULL)
  474.         return E_POINTER;
  475.  
  476.     HRESULT hr;
  477.     IObjectWithSite* pChildSite = NULL;
  478.     hr = punkChild->QueryInterface(IID_IObjectWithSite, (void**)&pChildSite);
  479.     if (SUCCEEDED(hr) && pChildSite != NULL)
  480.     {
  481.         hr = pChildSite->SetSite(punkParent);
  482.         pChildSite->Release();
  483.     }
  484.     return hr;
  485. }
  486.  
  487. template <class T>
  488. class _NoAddRefReleaseOnCComPtr : public T
  489. {
  490.     private:
  491.         STDMETHOD_(ULONG, AddRef)()=0;
  492.         STDMETHOD_(ULONG, Release)()=0;
  493. };
  494.  
  495. template <class T>
  496. class CComPtr
  497. {
  498. public:
  499.     typedef T _PtrClass;
  500.     CComPtr()
  501.     {
  502.         p=NULL;
  503.     }
  504.     CComPtr(T* lp)
  505.     {
  506.         if ((p = lp) != NULL)
  507.             p->AddRef();
  508.     }
  509.     CComPtr(const CComPtr<T>& lp)
  510.     {
  511.         if ((p = lp.p) != NULL)
  512.             p->AddRef();
  513.     }
  514.     ~CComPtr()
  515.     {
  516.         if (p)
  517.             p->Release();
  518.     }
  519.     void Release()
  520.     {
  521.         IUnknown* pTemp = p;
  522.         if (pTemp)
  523.         {
  524.             p = NULL;
  525.             pTemp->Release();
  526.         }
  527.     }
  528.     operator T*() const
  529.     {
  530.         return (T*)p;
  531.     }
  532.     T& operator*() const
  533.     {
  534.         ATLASSERT(p!=NULL);
  535.         return *p; 
  536.     }
  537.     //The assert on operator& usually indicates a bug.  If this is really
  538.     //what is needed, however, take the address of the p member explicitly.
  539.     T** operator&()
  540.     {
  541.         ATLASSERT(p==NULL);
  542.         return &p; 
  543.     }
  544.     _NoAddRefReleaseOnCComPtr<T>* operator->() const
  545.     {
  546.         ATLASSERT(p!=NULL);
  547.         return (_NoAddRefReleaseOnCComPtr<T>*)p;
  548.     }
  549.     T* operator=(T* lp)
  550.     {
  551.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp);
  552.     }
  553.     T* operator=(const CComPtr<T>& lp)
  554.     {
  555.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  556.     }
  557.     bool operator!() const
  558.     {
  559.         return (p == NULL);
  560.     }
  561.     bool operator<(T* pT) const
  562.     {
  563.         return p < pT;
  564.     }
  565.     bool operator==(T* pT) const
  566.     {
  567.         return p == pT;
  568.     }
  569.     // Compare two objects for equivalence
  570.     bool IsEqualObject(IUnknown* pOther)
  571.     {
  572.         if (p == NULL && pOther == NULL)
  573.             return true; // They are both NULL objects
  574.  
  575.         if (p == NULL || pOther == NULL)
  576.             return false; // One is NULL the other is not
  577.  
  578.         CComPtr<IUnknown> punk1;
  579.         CComPtr<IUnknown> punk2;
  580.         p->QueryInterface(IID_IUnknown, (void**)&punk1);
  581.         pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
  582.         return punk1 == punk2;
  583.     }
  584.     void Attach(T* p2)
  585.     {
  586.         if (p)
  587.             p->Release();
  588.         p = p2;
  589.     }
  590.     T* Detach()
  591.     {
  592.         T* pt = p;
  593.         p = NULL;
  594.         return pt;
  595.     }
  596.     HRESULT CopyTo(T** ppT)
  597.     {
  598.         ATLASSERT(ppT != NULL);
  599.         if (ppT == NULL)
  600.             return E_POINTER;
  601.         *ppT = p;
  602.         if (p)
  603.             p->AddRef();
  604.         return S_OK;
  605.     }
  606.     HRESULT SetSite(IUnknown* punkParent)
  607.     {
  608.         return AtlSetChildSite(p, punkParent);
  609.     }
  610.     HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  611.     {
  612.         return AtlAdvise(p, pUnk, iid, pdw);
  613.     }
  614.     HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  615.     {
  616.         ATLASSERT(p == NULL);
  617.         return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  618.     }
  619.     HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  620.     {
  621.         CLSID clsid;
  622.         HRESULT hr = WCE_FCTN(CLSIDFromProgID)(szProgID, &clsid);
  623.         ATLASSERT(p == NULL);
  624.         if (SUCCEEDED(hr))
  625.             hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  626.         return hr;
  627.     }
  628. #if !defined(_WIN32_WCE)
  629. // WinCE: our compilers don't support this kind of overloaded templated function
  630.     template <class Q>
  631.     HRESULT QueryInterface(Q** pp) const
  632.     {
  633.         ATLASSERT(pp != NULL && *pp == NULL);
  634.         return p->QueryInterface(__uuidof(Q), (void**)pp);
  635.     }
  636. #endif // _WIN32_WCE
  637.     T* p;
  638. };
  639.  
  640.  
  641. template <class T, const IID* piid = &__uuidof(T)>
  642. class CComQIPtr
  643. {
  644. public:
  645.     typedef T _PtrClass;
  646.     CComQIPtr()
  647.     {
  648.         p=NULL;
  649.     }
  650.     CComQIPtr(T* lp)
  651.     {
  652.         if ((p = lp) != NULL)
  653.             p->AddRef();
  654.     }
  655.     CComQIPtr(const CComQIPtr<T,piid>& lp)
  656.     {
  657.         if ((p = lp.p) != NULL)
  658.             p->AddRef();
  659.     }
  660.     CComQIPtr(IUnknown* lp)
  661.     {
  662.         p=NULL;
  663.         if (lp != NULL)
  664.             lp->QueryInterface(*piid, (void **)&p);
  665.     }
  666.     ~CComQIPtr()
  667.     {
  668.         if (p)
  669.             p->Release();
  670.     }
  671.     void Release()
  672.     {
  673.         IUnknown* pTemp = p;
  674.         if (pTemp)
  675.         {
  676.             p = NULL;
  677.             pTemp->Release();
  678.         }
  679.     }
  680.     operator T*() const
  681.     {
  682.         return p;
  683.     }
  684.     T& operator*() const
  685.     {
  686.         ATLASSERT(p!=NULL); return *p;
  687.     }
  688.     //The assert on operator& usually indicates a bug.  If this is really
  689.     //what is needed, however, take the address of the p member explicitly.
  690.     T** operator&()
  691.     {
  692.         ATLASSERT(p==NULL);
  693.         return &p;
  694.     }
  695.     _NoAddRefReleaseOnCComPtr<T>* operator->() const
  696.     {
  697.         ATLASSERT(p!=NULL);
  698.         return (_NoAddRefReleaseOnCComPtr<T>*)p;
  699.     }
  700.     T* operator=(T* lp)
  701.     {
  702.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp);
  703.     }
  704.     T* operator=(const CComQIPtr<T,piid>& lp)
  705.     {
  706.         return (T*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  707.     }
  708.     T* operator=(IUnknown* lp)
  709.     {
  710.         return (T*)AtlComQIPtrAssign((IUnknown**)&p, lp, *piid);
  711.     }
  712.     bool operator!() const
  713.     {
  714.         return (p == NULL);
  715.     }
  716.     bool operator<(T* pT) const
  717.     {
  718.         return p < pT;
  719.     }
  720.     bool operator==(T* pT) const
  721.     {
  722.         return p == pT;
  723.     }
  724.     // Compare two objects for equivalence
  725.     bool IsEqualObject(IUnknown* pOther)
  726.     {
  727.         if (p == NULL && pOther == NULL)
  728.             return true; // They are both NULL objects
  729.  
  730.         if (p == NULL || pOther == NULL)
  731.             return false; // One is NULL the other is not
  732.  
  733.         CComPtr<IUnknown> punk1;
  734.         CComPtr<IUnknown> punk2;
  735.         p->QueryInterface(IID_IUnknown, (void**)&punk1);
  736.         pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
  737.         return punk1 == punk2;
  738.     }
  739.     void Attach(T* p2)
  740.     {
  741.         if (p)
  742.             p->Release();
  743.         p = p2;
  744.     }
  745.     T* Detach()
  746.     {
  747.         T* pt = p;
  748.         p = NULL;
  749.         return pt;
  750.     }
  751.     HRESULT CopyTo(T** ppT)
  752.     {
  753.         ATLASSERT(ppT != NULL);
  754.         if (ppT == NULL)
  755.             return E_POINTER;
  756.         *ppT = p;
  757.         if (p)
  758.             p->AddRef();
  759.         return S_OK;
  760.     }
  761.     HRESULT SetSite(IUnknown* punkParent)
  762.     {
  763.         return AtlSetChildSite(p, punkParent);
  764.     }
  765.     HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  766.     {
  767.         return AtlAdvise(p, pUnk, iid, pdw);
  768.     }
  769.     HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  770.     {
  771.         ATLASSERT(p == NULL);
  772.         return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  773.     }
  774.     HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  775.     {
  776.         CLSID clsid;
  777.         HRESULT hr = WCE_FCTN(CLSIDFromProgID)(szProgID, &clsid);
  778.         ATLASSERT(p == NULL);
  779.         if (SUCCEEDED(hr))
  780.             hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  781.         return hr;
  782.     }
  783.     template <class Q>
  784.     HRESULT QueryInterface(Q** pp)
  785.     {
  786.         ATLASSERT(pp != NULL && *pp == NULL);
  787.         return p->QueryInterface(__uuidof(Q), (void**)pp);
  788.     }
  789.     T* p;
  790. };
  791.  
  792. //Specialization to make it work
  793. template<>
  794. class CComQIPtr<IUnknown, &IID_IUnknown>
  795. {
  796. public:
  797.     typedef IUnknown _PtrClass;
  798.     CComQIPtr()
  799.     {
  800.         p=NULL;
  801.     }
  802.     CComQIPtr(IUnknown* lp)
  803.     {
  804.         //Actually do a QI to get identity
  805.         p=NULL;
  806.         if (lp != NULL)
  807.             lp->QueryInterface(IID_IUnknown, (void **)&p);
  808.     }
  809.     CComQIPtr(const CComQIPtr<IUnknown,&IID_IUnknown>& lp)
  810.     {
  811.         if ((p = lp.p) != NULL)
  812.             p->AddRef();
  813.     }
  814.     ~CComQIPtr()
  815.     {
  816.         if (p)
  817.             p->Release();
  818.     }
  819.     void Release()
  820.     {
  821.         IUnknown* pTemp = p;
  822.         if (pTemp)
  823.         {
  824.             p = NULL;
  825.             pTemp->Release();
  826.         }
  827.     }
  828.     operator IUnknown*() const
  829.     {
  830.         return p;
  831.     }
  832.     IUnknown& operator*() const
  833.     {
  834.         ATLASSERT(p!=NULL);
  835.         return *p;
  836.     }
  837.     //The assert on operator& usually indicates a bug.  If this is really
  838.     //what is needed, however, take the address of the p member explicitly.
  839.     IUnknown** operator&()
  840.     {
  841.         ATLASSERT(p==NULL);
  842.         return &p;
  843.     }
  844.     _NoAddRefReleaseOnCComPtr<T>* operator->() const
  845.     {
  846.         ATLASSERT(p!=NULL);
  847.         return (_NoAddRefReleaseOnCComPtr<T>*)p;
  848.     }
  849.     IUnknown* operator=(IUnknown* lp)
  850.     {
  851.         //Actually do a QI to get identity
  852.         return (IUnknown*)AtlComQIPtrAssign((IUnknown**)&p, lp, IID_IUnknown);
  853.     }
  854.     IUnknown* operator=(const CComQIPtr<IUnknown,&IID_IUnknown>& lp)
  855.     {
  856.         return (IUnknown*)AtlComPtrAssign((IUnknown**)&p, lp.p);
  857.     }
  858.     bool operator!() const
  859.     {
  860.         return (p == NULL);
  861.     }
  862.     bool operator<(IUnknown* pT) const
  863.     {
  864.         return p < pT;
  865.     }
  866.     bool operator==(IUnknown* pT) const
  867.     {
  868.         return p == pT;
  869.     }
  870.     // Compare two objects for equivalence
  871.     bool IsEqualObject(IUnknown* pOther)
  872.     {
  873.         if (p == NULL && pOther == NULL)
  874.             return true; // They are both NULL objects
  875.  
  876.         if (p == NULL || pOther == NULL)
  877.             return false; // One is NULL the other is not
  878.  
  879.         CComPtr<IUnknown> punk1;
  880.         CComPtr<IUnknown> punk2;
  881.         p->QueryInterface(IID_IUnknown, (void**)&punk1);
  882.         pOther->QueryInterface(IID_IUnknown, (void**)&punk2);
  883.         return punk1 == punk2;
  884.     }
  885.     IUnknown* Detach()
  886.     {
  887.         IUnknown* pt = p;
  888.         p = NULL;
  889.         return pt;
  890.     }
  891.     HRESULT CopyTo(T** ppT)
  892.     {
  893.         ATLASSERT(ppT != NULL);
  894.         if (ppT == NULL)
  895.             return E_POINTER;
  896.         *ppT = p;
  897.         if (p)
  898.             p->AddRef();
  899.         return S_OK;
  900.     }
  901.     HRESULT SetSite(IUnknown* punkParent)
  902.     {
  903.         return AtlSetChildSite(p, punkParent);
  904.     }
  905.     HRESULT Advise(IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  906.     {
  907.         return AtlAdvise(p, pUnk, iid, pdw);
  908.     }
  909.     HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  910.     {
  911.         ATLASSERT(p == NULL);
  912.         return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  913.     }
  914.     HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
  915.     {
  916.         CLSID clsid;
  917.         HRESULT hr = WCE_FCTN(CLSIDFromProgID)(szProgID, &clsid);
  918.         ATLASSERT(p == NULL);
  919.         if (SUCCEEDED(hr))
  920.             hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
  921.         return hr;
  922.     }
  923.     template <class Q>
  924.     HRESULT QueryInterface(Q** pp)
  925.     {
  926.         ATLASSERT(pp != NULL && *pp == NULL);
  927.         return p->QueryInterface(__uuidof(Q), (void**)pp);
  928.     }
  929.     IUnknown* p;
  930. };
  931.  
  932. #define com_cast CComQIPtr
  933.  
  934. /////////////////////////////////////////////////////////////
  935. // Class to Adapt CComBSTR and CComPtr for use with STL containers
  936. // the syntax to use it is 
  937. // std::vector< CAdapt <CComBSTR> > vect;
  938.  
  939. template <class T>
  940. class CAdapt
  941. {
  942. public:
  943.     CAdapt()
  944.     {
  945.     }
  946.     CAdapt(const T& rSrc)
  947.     {
  948.         m_T = rSrc;
  949.     }
  950.  
  951.     CAdapt(const CAdapt& rSrCA)
  952.     {
  953.         m_T = rSrCA.m_T;
  954.     }
  955.  
  956.     CAdapt& operator=(const T& rSrc)
  957.     {
  958.         m_T = rSrc;
  959.         return *this;
  960.     }
  961.     bool operator<(const T& rSrc) const
  962.     {
  963.         return m_T < rSrc;
  964.     }
  965.     bool operator==(const T& rSrc) const
  966.     {
  967.         return m_T == rSrc;
  968.     }
  969.     operator T&()
  970.     {
  971.         return m_T;
  972.     }
  973.  
  974.     operator const T&() const
  975.     {
  976.         return m_T;
  977.     }
  978.  
  979.     T m_T;
  980. };
  981.  
  982. /////////////////////////////////////////////////////////////////////////////
  983. // GUID comparison
  984.  
  985. inline BOOL InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
  986. {
  987.    return (
  988.       ((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&
  989.       ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
  990.       ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
  991.       ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
  992. }
  993.  
  994. inline BOOL InlineIsEqualUnknown(REFGUID rguid1)
  995. {
  996.    return (
  997.       ((PLONG) &rguid1)[0] == 0 &&
  998.       ((PLONG) &rguid1)[1] == 0 &&
  999. #ifdef _ATL_BYTESWAP
  1000.       ((PLONG) &rguid1)[2] == 0xC0000000 &&
  1001.       ((PLONG) &rguid1)[3] == 0x00000046);
  1002. #else
  1003.       ((PLONG) &rguid1)[2] == 0x000000C0 &&
  1004.       ((PLONG) &rguid1)[3] == 0x46000000);
  1005. #endif
  1006. }
  1007.  
  1008. /////////////////////////////////////////////////////////////////////////////
  1009. // Threading Model Support
  1010.  
  1011.  
  1012. class CComCriticalSection
  1013. {
  1014. public:
  1015.     void Lock() {EnterCriticalSection(&m_sec);}
  1016.     void Unlock() {LeaveCriticalSection(&m_sec);}
  1017.     void Init() {InitializeCriticalSection(&m_sec);}
  1018.     void Term() {DeleteCriticalSection(&m_sec);}
  1019.     CRITICAL_SECTION m_sec;
  1020. };
  1021.  
  1022. class CComAutoCriticalSection
  1023. {
  1024. public:
  1025.     void Lock() {EnterCriticalSection(&m_sec);}
  1026.     void Unlock() {LeaveCriticalSection(&m_sec);}
  1027.     CComAutoCriticalSection() {InitializeCriticalSection(&m_sec);}
  1028.     ~CComAutoCriticalSection() {DeleteCriticalSection(&m_sec);}
  1029.     CRITICAL_SECTION m_sec;
  1030. };
  1031.  
  1032. class CComFakeCriticalSection
  1033. {
  1034. public:
  1035.     void Lock() {}
  1036.     void Unlock() {}
  1037.     void Init() {}
  1038.     void Term() {}
  1039. };
  1040.  
  1041.  
  1042. class CComMultiThreadModelNoCS
  1043. {
  1044. public:
  1045.     static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  1046.     static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  1047.     typedef CComFakeCriticalSection AutoCriticalSection;
  1048.     typedef CComFakeCriticalSection CriticalSection;
  1049.     typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  1050. };
  1051.  
  1052.  
  1053.  
  1054. class CComMultiThreadModel
  1055. {
  1056. public:
  1057.     static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  1058.     static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  1059.     typedef CComAutoCriticalSection AutoCriticalSection;
  1060.     typedef CComCriticalSection CriticalSection;
  1061.     typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  1062. };
  1063.  
  1064. class CComSingleThreadModel
  1065. {
  1066. public:
  1067.     static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
  1068.     static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
  1069.     typedef CComFakeCriticalSection AutoCriticalSection;
  1070.     typedef CComFakeCriticalSection CriticalSection;
  1071.     typedef CComSingleThreadModel ThreadModelNoCS;
  1072. };
  1073.  
  1074.  
  1075.  
  1076. #if defined(_ATL_SINGLE_THREADED)
  1077.     typedef CComSingleThreadModel CComObjectThreadModel;
  1078.     typedef CComSingleThreadModel CComGlobalsThreadModel;
  1079. #elif defined(_ATL_APARTMENT_THREADED)
  1080.     typedef CComSingleThreadModel CComObjectThreadModel;
  1081.     typedef CComMultiThreadModel CComGlobalsThreadModel;
  1082. #else
  1083.     typedef CComMultiThreadModel CComObjectThreadModel;
  1084.     typedef CComMultiThreadModel CComGlobalsThreadModel;
  1085. #endif
  1086.  
  1087. /////////////////////////////////////////////////////////////////////////////
  1088. // CComModule
  1089.  
  1090. #define THREADFLAGS_APARTMENT 0x1
  1091. #define THREADFLAGS_BOTH 0x2
  1092. #define AUTPRXFLAG 0x4
  1093.  
  1094. HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr);
  1095.  
  1096. #ifdef _ATL_DEBUG_INTERFACES
  1097. struct _QIThunk
  1098. {
  1099.     STDMETHOD(QueryInterface)(REFIID iid, void** pp)
  1100.     {
  1101.         ATLASSERT(m_dwRef >= 0);
  1102.         return pUnk->QueryInterface(iid, pp);
  1103.     }
  1104.     STDMETHOD_(ULONG, AddRef)()
  1105.     {
  1106.         if (bBreak)
  1107.             DebugBreak();
  1108.         pUnk->AddRef();
  1109.         return InternalAddRef();
  1110.     }
  1111.     ULONG InternalAddRef()
  1112.     {
  1113.         if (bBreak)
  1114.             DebugBreak();
  1115.         ATLASSERT(m_dwRef >= 0);
  1116.         long l = InterlockedIncrement(&m_dwRef);
  1117.         ATLTRACE(_T("%d> "), m_dwRef);
  1118.         AtlDumpIID(iid, lpszClassName, S_OK);
  1119.         if (l > m_dwMaxRef)
  1120.             m_dwMaxRef = l;
  1121.         return l;
  1122.     }
  1123.     STDMETHOD_(ULONG, Release)();
  1124.  
  1125.     STDMETHOD(f3)();
  1126.     STDMETHOD(f4)();
  1127.     STDMETHOD(f5)();
  1128.     STDMETHOD(f6)();
  1129.     STDMETHOD(f7)();
  1130.     STDMETHOD(f8)();
  1131.     STDMETHOD(f9)();
  1132.     STDMETHOD(f10)();
  1133.     STDMETHOD(f11)();
  1134.     STDMETHOD(f12)();
  1135.     STDMETHOD(f13)();
  1136.     STDMETHOD(f14)();
  1137.     STDMETHOD(f15)();
  1138.     STDMETHOD(f16)();
  1139.     STDMETHOD(f17)();
  1140.     STDMETHOD(f18)();
  1141.     STDMETHOD(f19)();
  1142.     STDMETHOD(f20)();
  1143.     STDMETHOD(f21)();
  1144.     STDMETHOD(f22)();
  1145.     STDMETHOD(f23)();
  1146.     STDMETHOD(f24)();
  1147.     STDMETHOD(f25)();
  1148.     STDMETHOD(f26)();
  1149.     STDMETHOD(f27)();
  1150.     STDMETHOD(f28)();
  1151.     STDMETHOD(f29)();
  1152.     STDMETHOD(f30)();
  1153.     STDMETHOD(f31)();
  1154.     STDMETHOD(f32)();
  1155.     STDMETHOD(f33)();
  1156.     STDMETHOD(f34)();
  1157.     STDMETHOD(f35)();
  1158.     STDMETHOD(f36)();
  1159.     STDMETHOD(f37)();
  1160.     STDMETHOD(f38)();
  1161.     STDMETHOD(f39)();
  1162.     STDMETHOD(f40)();
  1163.     STDMETHOD(f41)();
  1164.     STDMETHOD(f42)();
  1165.     STDMETHOD(f43)();
  1166.     STDMETHOD(f44)();
  1167.     STDMETHOD(f45)();
  1168.     STDMETHOD(f46)();
  1169.     STDMETHOD(f47)();
  1170.     STDMETHOD(f48)();
  1171.     STDMETHOD(f49)();
  1172.     STDMETHOD(f50)();
  1173.     STDMETHOD(f51)();
  1174.     STDMETHOD(f52)();
  1175.     STDMETHOD(f53)();
  1176.     STDMETHOD(f54)();
  1177.     STDMETHOD(f55)();
  1178.     STDMETHOD(f56)();
  1179.     STDMETHOD(f57)();
  1180.     STDMETHOD(f58)();
  1181.     STDMETHOD(f59)();
  1182.     STDMETHOD(f60)();
  1183.     STDMETHOD(f61)();
  1184.     STDMETHOD(f62)();
  1185.     STDMETHOD(f63)();
  1186.     STDMETHOD(f64)();
  1187.     STDMETHOD(f65)();
  1188.     STDMETHOD(f66)();
  1189.     STDMETHOD(f67)();
  1190.     STDMETHOD(f68)();
  1191.     STDMETHOD(f69)();
  1192.     STDMETHOD(f70)();
  1193.     STDMETHOD(f71)();
  1194.     STDMETHOD(f72)();
  1195.     STDMETHOD(f73)();
  1196.     STDMETHOD(f74)();
  1197.     STDMETHOD(f75)();
  1198.     STDMETHOD(f76)();
  1199.     STDMETHOD(f77)();
  1200.     STDMETHOD(f78)();
  1201.     STDMETHOD(f79)();
  1202.     STDMETHOD(f80)();
  1203.     STDMETHOD(f81)();
  1204.     STDMETHOD(f82)();
  1205.     STDMETHOD(f83)();
  1206.     STDMETHOD(f84)();
  1207.     STDMETHOD(f85)();
  1208.     STDMETHOD(f86)();
  1209.     STDMETHOD(f87)();
  1210.     STDMETHOD(f88)();
  1211.     STDMETHOD(f89)();
  1212.     STDMETHOD(f90)();
  1213.     STDMETHOD(f91)();
  1214.     STDMETHOD(f92)();
  1215.     STDMETHOD(f93)();
  1216.     STDMETHOD(f94)();
  1217.     STDMETHOD(f95)();
  1218.     STDMETHOD(f96)();
  1219.     STDMETHOD(f97)();
  1220.     STDMETHOD(f98)();
  1221.     STDMETHOD(f99)();
  1222.     STDMETHOD(f100)();
  1223.     STDMETHOD(f101)();
  1224.     STDMETHOD(f102)();
  1225.     STDMETHOD(f103)();
  1226.     STDMETHOD(f104)();
  1227.     STDMETHOD(f105)();
  1228.     STDMETHOD(f106)();
  1229.     STDMETHOD(f107)();
  1230.     STDMETHOD(f108)();
  1231.     STDMETHOD(f109)();
  1232.     STDMETHOD(f110)();
  1233.     STDMETHOD(f111)();
  1234.     STDMETHOD(f112)();
  1235.     STDMETHOD(f113)();
  1236.     STDMETHOD(f114)();
  1237.     STDMETHOD(f115)();
  1238.     STDMETHOD(f116)();
  1239.     STDMETHOD(f117)();
  1240.     STDMETHOD(f118)();
  1241.     STDMETHOD(f119)();
  1242.     STDMETHOD(f120)();
  1243.     STDMETHOD(f121)();
  1244.     STDMETHOD(f122)();
  1245.     STDMETHOD(f123)();
  1246.     STDMETHOD(f124)();
  1247.     STDMETHOD(f125)();
  1248.     STDMETHOD(f126)();
  1249.     STDMETHOD(f127)();
  1250.     STDMETHOD(f128)();
  1251.     STDMETHOD(f129)();
  1252.     STDMETHOD(f130)();
  1253.     STDMETHOD(f131)();
  1254.     STDMETHOD(f132)();
  1255.     STDMETHOD(f133)();
  1256.     STDMETHOD(f134)();
  1257.     STDMETHOD(f135)();
  1258.     STDMETHOD(f136)();
  1259.     STDMETHOD(f137)();
  1260.     STDMETHOD(f138)();
  1261.     STDMETHOD(f139)();
  1262.     STDMETHOD(f140)();
  1263.     STDMETHOD(f141)();
  1264.     STDMETHOD(f142)();
  1265.     STDMETHOD(f143)();
  1266.     STDMETHOD(f144)();
  1267.     STDMETHOD(f145)();
  1268.     STDMETHOD(f146)();
  1269.     STDMETHOD(f147)();
  1270.     STDMETHOD(f148)();
  1271.     STDMETHOD(f149)();
  1272.     STDMETHOD(f150)();
  1273.     STDMETHOD(f151)();
  1274.     STDMETHOD(f152)();
  1275.     STDMETHOD(f153)();
  1276.     STDMETHOD(f154)();
  1277.     STDMETHOD(f155)();
  1278.     STDMETHOD(f156)();
  1279.     STDMETHOD(f157)();
  1280.     STDMETHOD(f158)();
  1281.     STDMETHOD(f159)();
  1282.     STDMETHOD(f160)();
  1283.     STDMETHOD(f161)();
  1284.     STDMETHOD(f162)();
  1285.     STDMETHOD(f163)();
  1286.     STDMETHOD(f164)();
  1287.     STDMETHOD(f165)();
  1288.     STDMETHOD(f166)();
  1289.     STDMETHOD(f167)();
  1290.     STDMETHOD(f168)();
  1291.     STDMETHOD(f169)();
  1292.     STDMETHOD(f170)();
  1293.     STDMETHOD(f171)();
  1294.     STDMETHOD(f172)();
  1295.     STDMETHOD(f173)();
  1296.     STDMETHOD(f174)();
  1297.     STDMETHOD(f175)();
  1298.     STDMETHOD(f176)();
  1299.     STDMETHOD(f177)();
  1300.     STDMETHOD(f178)();
  1301.     STDMETHOD(f179)();
  1302.     STDMETHOD(f180)();
  1303.     STDMETHOD(f181)();
  1304.     STDMETHOD(f182)();
  1305.     STDMETHOD(f183)();
  1306.     STDMETHOD(f184)();
  1307.     STDMETHOD(f185)();
  1308.     STDMETHOD(f186)();
  1309.     STDMETHOD(f187)();
  1310.     STDMETHOD(f188)();
  1311.     STDMETHOD(f189)();
  1312.     STDMETHOD(f190)();
  1313.     STDMETHOD(f191)();
  1314.     STDMETHOD(f192)();
  1315.     STDMETHOD(f193)();
  1316.     STDMETHOD(f194)();
  1317.     STDMETHOD(f195)();
  1318.     STDMETHOD(f196)();
  1319.     STDMETHOD(f197)();
  1320.     STDMETHOD(f198)();
  1321.     STDMETHOD(f199)();
  1322.     STDMETHOD(f200)();
  1323.     STDMETHOD(f201)();
  1324.     STDMETHOD(f202)();
  1325.     STDMETHOD(f203)();
  1326.     STDMETHOD(f204)();
  1327.     STDMETHOD(f205)();
  1328.     STDMETHOD(f206)();
  1329.     STDMETHOD(f207)();
  1330.     STDMETHOD(f208)();
  1331.     STDMETHOD(f209)();
  1332.     STDMETHOD(f210)();
  1333.     STDMETHOD(f211)();
  1334.     STDMETHOD(f212)();
  1335.     STDMETHOD(f213)();
  1336.     STDMETHOD(f214)();
  1337.     STDMETHOD(f215)();
  1338.     STDMETHOD(f216)();
  1339.     STDMETHOD(f217)();
  1340.     STDMETHOD(f218)();
  1341.     STDMETHOD(f219)();
  1342.     STDMETHOD(f220)();
  1343.     STDMETHOD(f221)();
  1344.     STDMETHOD(f222)();
  1345.     STDMETHOD(f223)();
  1346.     STDMETHOD(f224)();
  1347.     STDMETHOD(f225)();
  1348.     STDMETHOD(f226)();
  1349.     STDMETHOD(f227)();
  1350.     STDMETHOD(f228)();
  1351.     STDMETHOD(f229)();
  1352.     STDMETHOD(f230)();
  1353.     STDMETHOD(f231)();
  1354.     STDMETHOD(f232)();
  1355.     STDMETHOD(f233)();
  1356.     STDMETHOD(f234)();
  1357.     STDMETHOD(f235)();
  1358.     STDMETHOD(f236)();
  1359.     STDMETHOD(f237)();
  1360.     STDMETHOD(f238)();
  1361.     STDMETHOD(f239)();
  1362.     STDMETHOD(f240)();
  1363.     STDMETHOD(f241)();
  1364.     STDMETHOD(f242)();
  1365.     STDMETHOD(f243)();
  1366.     STDMETHOD(f244)();
  1367.     STDMETHOD(f245)();
  1368.     STDMETHOD(f246)();
  1369.     STDMETHOD(f247)();
  1370.     STDMETHOD(f248)();
  1371.     STDMETHOD(f249)();
  1372.     STDMETHOD(f250)();
  1373.     STDMETHOD(f251)();
  1374.     STDMETHOD(f252)();
  1375.     STDMETHOD(f253)();
  1376.     STDMETHOD(f254)();
  1377.     STDMETHOD(f255)();
  1378.     STDMETHOD(f256)();
  1379.     STDMETHOD(f257)();
  1380.     STDMETHOD(f258)();
  1381.     STDMETHOD(f259)();
  1382.     STDMETHOD(f260)();
  1383.     STDMETHOD(f261)();
  1384.     STDMETHOD(f262)();
  1385.     STDMETHOD(f263)();
  1386.     STDMETHOD(f264)();
  1387.     STDMETHOD(f265)();
  1388.     STDMETHOD(f266)();
  1389.     STDMETHOD(f267)();
  1390.     STDMETHOD(f268)();
  1391.     STDMETHOD(f269)();
  1392.     STDMETHOD(f270)();
  1393.     STDMETHOD(f271)();
  1394.     STDMETHOD(f272)();
  1395.     STDMETHOD(f273)();
  1396.     STDMETHOD(f274)();
  1397.     STDMETHOD(f275)();
  1398.     STDMETHOD(f276)();
  1399.     STDMETHOD(f277)();
  1400.     STDMETHOD(f278)();
  1401.     STDMETHOD(f279)();
  1402.     STDMETHOD(f280)();
  1403.     STDMETHOD(f281)();
  1404.     STDMETHOD(f282)();
  1405.     STDMETHOD(f283)();
  1406.     STDMETHOD(f284)();
  1407.     STDMETHOD(f285)();
  1408.     STDMETHOD(f286)();
  1409.     STDMETHOD(f287)();
  1410.     STDMETHOD(f288)();
  1411.     STDMETHOD(f289)();
  1412.     STDMETHOD(f290)();
  1413.     STDMETHOD(f291)();
  1414.     STDMETHOD(f292)();
  1415.     STDMETHOD(f293)();
  1416.     STDMETHOD(f294)();
  1417.     STDMETHOD(f295)();
  1418.     STDMETHOD(f296)();
  1419.     STDMETHOD(f297)();
  1420.     STDMETHOD(f298)();
  1421.     STDMETHOD(f299)();
  1422.     STDMETHOD(f300)();
  1423.     STDMETHOD(f301)();
  1424.     STDMETHOD(f302)();
  1425.     STDMETHOD(f303)();
  1426.     STDMETHOD(f304)();
  1427.     STDMETHOD(f305)();
  1428.     STDMETHOD(f306)();
  1429.     STDMETHOD(f307)();
  1430.     STDMETHOD(f308)();
  1431.     STDMETHOD(f309)();
  1432.     STDMETHOD(f310)();
  1433.     STDMETHOD(f311)();
  1434.     STDMETHOD(f312)();
  1435.     STDMETHOD(f313)();
  1436.     STDMETHOD(f314)();
  1437.     STDMETHOD(f315)();
  1438.     STDMETHOD(f316)();
  1439.     STDMETHOD(f317)();
  1440.     STDMETHOD(f318)();
  1441.     STDMETHOD(f319)();
  1442.     STDMETHOD(f320)();
  1443.     STDMETHOD(f321)();
  1444.     STDMETHOD(f322)();
  1445.     STDMETHOD(f323)();
  1446.     STDMETHOD(f324)();
  1447.     STDMETHOD(f325)();
  1448.     STDMETHOD(f326)();
  1449.     STDMETHOD(f327)();
  1450.     STDMETHOD(f328)();
  1451.     STDMETHOD(f329)();
  1452.     STDMETHOD(f330)();
  1453.     STDMETHOD(f331)();
  1454.     STDMETHOD(f332)();
  1455.     STDMETHOD(f333)();
  1456.     STDMETHOD(f334)();
  1457.     STDMETHOD(f335)();
  1458.     STDMETHOD(f336)();
  1459.     STDMETHOD(f337)();
  1460.     STDMETHOD(f338)();
  1461.     STDMETHOD(f339)();
  1462.     STDMETHOD(f340)();
  1463.     STDMETHOD(f341)();
  1464.     STDMETHOD(f342)();
  1465.     STDMETHOD(f343)();
  1466.     STDMETHOD(f344)();
  1467.     STDMETHOD(f345)();
  1468.     STDMETHOD(f346)();
  1469.     STDMETHOD(f347)();
  1470.     STDMETHOD(f348)();
  1471.     STDMETHOD(f349)();
  1472.     STDMETHOD(f350)();
  1473.     STDMETHOD(f351)();
  1474.     STDMETHOD(f352)();
  1475.     STDMETHOD(f353)();
  1476.     STDMETHOD(f354)();
  1477.     STDMETHOD(f355)();
  1478.     STDMETHOD(f356)();
  1479.     STDMETHOD(f357)();
  1480.     STDMETHOD(f358)();
  1481.     STDMETHOD(f359)();
  1482.     STDMETHOD(f360)();
  1483.     STDMETHOD(f361)();
  1484.     STDMETHOD(f362)();
  1485.     STDMETHOD(f363)();
  1486.     STDMETHOD(f364)();
  1487.     STDMETHOD(f365)();
  1488.     STDMETHOD(f366)();
  1489.     STDMETHOD(f367)();
  1490.     STDMETHOD(f368)();
  1491.     STDMETHOD(f369)();
  1492.     STDMETHOD(f370)();
  1493.     STDMETHOD(f371)();
  1494.     STDMETHOD(f372)();
  1495.     STDMETHOD(f373)();
  1496.     STDMETHOD(f374)();
  1497.     STDMETHOD(f375)();
  1498.     STDMETHOD(f376)();
  1499.     STDMETHOD(f377)();
  1500.     STDMETHOD(f378)();
  1501.     STDMETHOD(f379)();
  1502.     STDMETHOD(f380)();
  1503.     STDMETHOD(f381)();
  1504.     STDMETHOD(f382)();
  1505.     STDMETHOD(f383)();
  1506.     STDMETHOD(f384)();
  1507.     STDMETHOD(f385)();
  1508.     STDMETHOD(f386)();
  1509.     STDMETHOD(f387)();
  1510.     STDMETHOD(f388)();
  1511.     STDMETHOD(f389)();
  1512.     STDMETHOD(f390)();
  1513.     STDMETHOD(f391)();
  1514.     STDMETHOD(f392)();
  1515.     STDMETHOD(f393)();
  1516.     STDMETHOD(f394)();
  1517.     STDMETHOD(f395)();
  1518.     STDMETHOD(f396)();
  1519.     STDMETHOD(f397)();
  1520.     STDMETHOD(f398)();
  1521.     STDMETHOD(f399)();
  1522.     STDMETHOD(f400)();
  1523.     STDMETHOD(f401)();
  1524.     STDMETHOD(f402)();
  1525.     STDMETHOD(f403)();
  1526.     STDMETHOD(f404)();
  1527.     STDMETHOD(f405)();
  1528.     STDMETHOD(f406)();
  1529.     STDMETHOD(f407)();
  1530.     STDMETHOD(f408)();
  1531.     STDMETHOD(f409)();
  1532.     STDMETHOD(f410)();
  1533.     STDMETHOD(f411)();
  1534.     STDMETHOD(f412)();
  1535.     STDMETHOD(f413)();
  1536.     STDMETHOD(f414)();
  1537.     STDMETHOD(f415)();
  1538.     STDMETHOD(f416)();
  1539.     STDMETHOD(f417)();
  1540.     STDMETHOD(f418)();
  1541.     STDMETHOD(f419)();
  1542.     STDMETHOD(f420)();
  1543.     STDMETHOD(f421)();
  1544.     STDMETHOD(f422)();
  1545.     STDMETHOD(f423)();
  1546.     STDMETHOD(f424)();
  1547.     STDMETHOD(f425)();
  1548.     STDMETHOD(f426)();
  1549.     STDMETHOD(f427)();
  1550.     STDMETHOD(f428)();
  1551.     STDMETHOD(f429)();
  1552.     STDMETHOD(f430)();
  1553.     STDMETHOD(f431)();
  1554.     STDMETHOD(f432)();
  1555.     STDMETHOD(f433)();
  1556.     STDMETHOD(f434)();
  1557.     STDMETHOD(f435)();
  1558.     STDMETHOD(f436)();
  1559.     STDMETHOD(f437)();
  1560.     STDMETHOD(f438)();
  1561.     STDMETHOD(f439)();
  1562.     STDMETHOD(f440)();
  1563.     STDMETHOD(f441)();
  1564.     STDMETHOD(f442)();
  1565.     STDMETHOD(f443)();
  1566.     STDMETHOD(f444)();
  1567.     STDMETHOD(f445)();
  1568.     STDMETHOD(f446)();
  1569.     STDMETHOD(f447)();
  1570.     STDMETHOD(f448)();
  1571.     STDMETHOD(f449)();
  1572.     STDMETHOD(f450)();
  1573.     STDMETHOD(f451)();
  1574.     STDMETHOD(f452)();
  1575.     STDMETHOD(f453)();
  1576.     STDMETHOD(f454)();
  1577.     STDMETHOD(f455)();
  1578.     STDMETHOD(f456)();
  1579.     STDMETHOD(f457)();
  1580.     STDMETHOD(f458)();
  1581.     STDMETHOD(f459)();
  1582.     STDMETHOD(f460)();
  1583.     STDMETHOD(f461)();
  1584.     STDMETHOD(f462)();
  1585.     STDMETHOD(f463)();
  1586.     STDMETHOD(f464)();
  1587.     STDMETHOD(f465)();
  1588.     STDMETHOD(f466)();
  1589.     STDMETHOD(f467)();
  1590.     STDMETHOD(f468)();
  1591.     STDMETHOD(f469)();
  1592.     STDMETHOD(f470)();
  1593.     STDMETHOD(f471)();
  1594.     STDMETHOD(f472)();
  1595.     STDMETHOD(f473)();
  1596.     STDMETHOD(f474)();
  1597.     STDMETHOD(f475)();
  1598.     STDMETHOD(f476)();
  1599.     STDMETHOD(f477)();
  1600.     STDMETHOD(f478)();
  1601.     STDMETHOD(f479)();
  1602.     STDMETHOD(f480)();
  1603.     STDMETHOD(f481)();
  1604.     STDMETHOD(f482)();
  1605.     STDMETHOD(f483)();
  1606.     STDMETHOD(f484)();
  1607.     STDMETHOD(f485)();
  1608.     STDMETHOD(f486)();
  1609.     STDMETHOD(f487)();
  1610.     STDMETHOD(f488)();
  1611.     STDMETHOD(f489)();
  1612.     STDMETHOD(f490)();
  1613.     STDMETHOD(f491)();
  1614.     STDMETHOD(f492)();
  1615.     STDMETHOD(f493)();
  1616.     STDMETHOD(f494)();
  1617.     STDMETHOD(f495)();
  1618.     STDMETHOD(f496)();
  1619.     STDMETHOD(f497)();
  1620.     STDMETHOD(f498)();
  1621.     STDMETHOD(f499)();
  1622.     STDMETHOD(f500)();
  1623.     STDMETHOD(f501)();
  1624.     STDMETHOD(f502)();
  1625.     STDMETHOD(f503)();
  1626.     STDMETHOD(f504)();
  1627.     STDMETHOD(f505)();
  1628.     STDMETHOD(f506)();
  1629.     STDMETHOD(f507)();
  1630.     STDMETHOD(f508)();
  1631.     STDMETHOD(f509)();
  1632.     STDMETHOD(f510)();
  1633.     STDMETHOD(f511)();
  1634.     STDMETHOD(f512)();
  1635.     STDMETHOD(f513)();
  1636.     STDMETHOD(f514)();
  1637.     STDMETHOD(f515)();
  1638.     STDMETHOD(f516)();
  1639.     STDMETHOD(f517)();
  1640.     STDMETHOD(f518)();
  1641.     STDMETHOD(f519)();
  1642.     STDMETHOD(f520)();
  1643.     STDMETHOD(f521)();
  1644.     STDMETHOD(f522)();
  1645.     STDMETHOD(f523)();
  1646.     STDMETHOD(f524)();
  1647.     STDMETHOD(f525)();
  1648.     STDMETHOD(f526)();
  1649.     STDMETHOD(f527)();
  1650.     STDMETHOD(f528)();
  1651.     STDMETHOD(f529)();
  1652.     STDMETHOD(f530)();
  1653.     STDMETHOD(f531)();
  1654.     STDMETHOD(f532)();
  1655.     STDMETHOD(f533)();
  1656.     STDMETHOD(f534)();
  1657.     STDMETHOD(f535)();
  1658.     STDMETHOD(f536)();
  1659.     STDMETHOD(f537)();
  1660.     STDMETHOD(f538)();
  1661.     STDMETHOD(f539)();
  1662.     STDMETHOD(f540)();
  1663.     STDMETHOD(f541)();
  1664.     STDMETHOD(f542)();
  1665.     STDMETHOD(f543)();
  1666.     STDMETHOD(f544)();
  1667.     STDMETHOD(f545)();
  1668.     STDMETHOD(f546)();
  1669.     STDMETHOD(f547)();
  1670.     STDMETHOD(f548)();
  1671.     STDMETHOD(f549)();
  1672.     STDMETHOD(f550)();
  1673.     STDMETHOD(f551)();
  1674.     STDMETHOD(f552)();
  1675.     STDMETHOD(f553)();
  1676.     STDMETHOD(f554)();
  1677.     STDMETHOD(f555)();
  1678.     STDMETHOD(f556)();
  1679.     STDMETHOD(f557)();
  1680.     STDMETHOD(f558)();
  1681.     STDMETHOD(f559)();
  1682.     STDMETHOD(f560)();
  1683.     STDMETHOD(f561)();
  1684.     STDMETHOD(f562)();
  1685.     STDMETHOD(f563)();
  1686.     STDMETHOD(f564)();
  1687.     STDMETHOD(f565)();
  1688.     STDMETHOD(f566)();
  1689.     STDMETHOD(f567)();
  1690.     STDMETHOD(f568)();
  1691.     STDMETHOD(f569)();
  1692.     STDMETHOD(f570)();
  1693.     STDMETHOD(f571)();
  1694.     STDMETHOD(f572)();
  1695.     STDMETHOD(f573)();
  1696.     STDMETHOD(f574)();
  1697.     STDMETHOD(f575)();
  1698.     STDMETHOD(f576)();
  1699.     STDMETHOD(f577)();
  1700.     STDMETHOD(f578)();
  1701.     STDMETHOD(f579)();
  1702.     STDMETHOD(f580)();
  1703.     STDMETHOD(f581)();
  1704.     STDMETHOD(f582)();
  1705.     STDMETHOD(f583)();
  1706.     STDMETHOD(f584)();
  1707.     STDMETHOD(f585)();
  1708.     STDMETHOD(f586)();
  1709.     STDMETHOD(f587)();
  1710.     STDMETHOD(f588)();
  1711.     STDMETHOD(f589)();
  1712.     STDMETHOD(f590)();
  1713.     STDMETHOD(f591)();
  1714.     STDMETHOD(f592)();
  1715.     STDMETHOD(f593)();
  1716.     STDMETHOD(f594)();
  1717.     STDMETHOD(f595)();
  1718.     STDMETHOD(f596)();
  1719.     STDMETHOD(f597)();
  1720.     STDMETHOD(f598)();
  1721.     STDMETHOD(f599)();
  1722.     STDMETHOD(f600)();
  1723.     STDMETHOD(f601)();
  1724.     STDMETHOD(f602)();
  1725.     STDMETHOD(f603)();
  1726.     STDMETHOD(f604)();
  1727.     STDMETHOD(f605)();
  1728.     STDMETHOD(f606)();
  1729.     STDMETHOD(f607)();
  1730.     STDMETHOD(f608)();
  1731.     STDMETHOD(f609)();
  1732.     STDMETHOD(f610)();
  1733.     STDMETHOD(f611)();
  1734.     STDMETHOD(f612)();
  1735.     STDMETHOD(f613)();
  1736.     STDMETHOD(f614)();
  1737.     STDMETHOD(f615)();
  1738.     STDMETHOD(f616)();
  1739.     STDMETHOD(f617)();
  1740.     STDMETHOD(f618)();
  1741.     STDMETHOD(f619)();
  1742.     STDMETHOD(f620)();
  1743.     STDMETHOD(f621)();
  1744.     STDMETHOD(f622)();
  1745.     STDMETHOD(f623)();
  1746.     STDMETHOD(f624)();
  1747.     STDMETHOD(f625)();
  1748.     STDMETHOD(f626)();
  1749.     STDMETHOD(f627)();
  1750.     STDMETHOD(f628)();
  1751.     STDMETHOD(f629)();
  1752.     STDMETHOD(f630)();
  1753.     STDMETHOD(f631)();
  1754.     STDMETHOD(f632)();
  1755.     STDMETHOD(f633)();
  1756.     STDMETHOD(f634)();
  1757.     STDMETHOD(f635)();
  1758.     STDMETHOD(f636)();
  1759.     STDMETHOD(f637)();
  1760.     STDMETHOD(f638)();
  1761.     STDMETHOD(f639)();
  1762.     STDMETHOD(f640)();
  1763.     STDMETHOD(f641)();
  1764.     STDMETHOD(f642)();
  1765.     STDMETHOD(f643)();
  1766.     STDMETHOD(f644)();
  1767.     STDMETHOD(f645)();
  1768.     STDMETHOD(f646)();
  1769.     STDMETHOD(f647)();
  1770.     STDMETHOD(f648)();
  1771.     STDMETHOD(f649)();
  1772.     STDMETHOD(f650)();
  1773.     STDMETHOD(f651)();
  1774.     STDMETHOD(f652)();
  1775.     STDMETHOD(f653)();
  1776.     STDMETHOD(f654)();
  1777.     STDMETHOD(f655)();
  1778.     STDMETHOD(f656)();
  1779.     STDMETHOD(f657)();
  1780.     STDMETHOD(f658)();
  1781.     STDMETHOD(f659)();
  1782.     STDMETHOD(f660)();
  1783.     STDMETHOD(f661)();
  1784.     STDMETHOD(f662)();
  1785.     STDMETHOD(f663)();
  1786.     STDMETHOD(f664)();
  1787.     STDMETHOD(f665)();
  1788.     STDMETHOD(f666)();
  1789.     STDMETHOD(f667)();
  1790.     STDMETHOD(f668)();
  1791.     STDMETHOD(f669)();
  1792.     STDMETHOD(f670)();
  1793.     STDMETHOD(f671)();
  1794.     STDMETHOD(f672)();
  1795.     STDMETHOD(f673)();
  1796.     STDMETHOD(f674)();
  1797.     STDMETHOD(f675)();
  1798.     STDMETHOD(f676)();
  1799.     STDMETHOD(f677)();
  1800.     STDMETHOD(f678)();
  1801.     STDMETHOD(f679)();
  1802.     STDMETHOD(f680)();
  1803.     STDMETHOD(f681)();
  1804.     STDMETHOD(f682)();
  1805.     STDMETHOD(f683)();
  1806.     STDMETHOD(f684)();
  1807.     STDMETHOD(f685)();
  1808.     STDMETHOD(f686)();
  1809.     STDMETHOD(f687)();
  1810.     STDMETHOD(f688)();
  1811.     STDMETHOD(f689)();
  1812.     STDMETHOD(f690)();
  1813.     STDMETHOD(f691)();
  1814.     STDMETHOD(f692)();
  1815.     STDMETHOD(f693)();
  1816.     STDMETHOD(f694)();
  1817.     STDMETHOD(f695)();
  1818.     STDMETHOD(f696)();
  1819.     STDMETHOD(f697)();
  1820.     STDMETHOD(f698)();
  1821.     STDMETHOD(f699)();
  1822.     STDMETHOD(f700)();
  1823.     STDMETHOD(f701)();
  1824.     STDMETHOD(f702)();
  1825.     STDMETHOD(f703)();
  1826.     STDMETHOD(f704)();
  1827.     STDMETHOD(f705)();
  1828.     STDMETHOD(f706)();
  1829.     STDMETHOD(f707)();
  1830.     STDMETHOD(f708)();
  1831.     STDMETHOD(f709)();
  1832.     STDMETHOD(f710)();
  1833.     STDMETHOD(f711)();
  1834.     STDMETHOD(f712)();
  1835.     STDMETHOD(f713)();
  1836.     STDMETHOD(f714)();
  1837.     STDMETHOD(f715)();
  1838.     STDMETHOD(f716)();
  1839.     STDMETHOD(f717)();
  1840.     STDMETHOD(f718)();
  1841.     STDMETHOD(f719)();
  1842.     STDMETHOD(f720)();
  1843.     STDMETHOD(f721)();
  1844.     STDMETHOD(f722)();
  1845.     STDMETHOD(f723)();
  1846.     STDMETHOD(f724)();
  1847.     STDMETHOD(f725)();
  1848.     STDMETHOD(f726)();
  1849.     STDMETHOD(f727)();
  1850.     STDMETHOD(f728)();
  1851.     STDMETHOD(f729)();
  1852.     STDMETHOD(f730)();
  1853.     STDMETHOD(f731)();
  1854.     STDMETHOD(f732)();
  1855.     STDMETHOD(f733)();
  1856.     STDMETHOD(f734)();
  1857.     STDMETHOD(f735)();
  1858.     STDMETHOD(f736)();
  1859.     STDMETHOD(f737)();
  1860.     STDMETHOD(f738)();
  1861.     STDMETHOD(f739)();
  1862.     STDMETHOD(f740)();
  1863.     STDMETHOD(f741)();
  1864.     STDMETHOD(f742)();
  1865.     STDMETHOD(f743)();
  1866.     STDMETHOD(f744)();
  1867.     STDMETHOD(f745)();
  1868.     STDMETHOD(f746)();
  1869.     STDMETHOD(f747)();
  1870.     STDMETHOD(f748)();
  1871.     STDMETHOD(f749)();
  1872.     STDMETHOD(f750)();
  1873.     STDMETHOD(f751)();
  1874.     STDMETHOD(f752)();
  1875.     STDMETHOD(f753)();
  1876.     STDMETHOD(f754)();
  1877.     STDMETHOD(f755)();
  1878.     STDMETHOD(f756)();
  1879.     STDMETHOD(f757)();
  1880.     STDMETHOD(f758)();
  1881.     STDMETHOD(f759)();
  1882.     STDMETHOD(f760)();
  1883.     STDMETHOD(f761)();
  1884.     STDMETHOD(f762)();
  1885.     STDMETHOD(f763)();
  1886.     STDMETHOD(f764)();
  1887.     STDMETHOD(f765)();
  1888.     STDMETHOD(f766)();
  1889.     STDMETHOD(f767)();
  1890.     STDMETHOD(f768)();
  1891.     STDMETHOD(f769)();
  1892.     STDMETHOD(f770)();
  1893.     STDMETHOD(f771)();
  1894.     STDMETHOD(f772)();
  1895.     STDMETHOD(f773)();
  1896.     STDMETHOD(f774)();
  1897.     STDMETHOD(f775)();
  1898.     STDMETHOD(f776)();
  1899.     STDMETHOD(f777)();
  1900.     STDMETHOD(f778)();
  1901.     STDMETHOD(f779)();
  1902.     STDMETHOD(f780)();
  1903.     STDMETHOD(f781)();
  1904.     STDMETHOD(f782)();
  1905.     STDMETHOD(f783)();
  1906.     STDMETHOD(f784)();
  1907.     STDMETHOD(f785)();
  1908.     STDMETHOD(f786)();
  1909.     STDMETHOD(f787)();
  1910.     STDMETHOD(f788)();
  1911.     STDMETHOD(f789)();
  1912.     STDMETHOD(f790)();
  1913.     STDMETHOD(f791)();
  1914.     STDMETHOD(f792)();
  1915.     STDMETHOD(f793)();
  1916.     STDMETHOD(f794)();
  1917.     STDMETHOD(f795)();
  1918.     STDMETHOD(f796)();
  1919.     STDMETHOD(f797)();
  1920.     STDMETHOD(f798)();
  1921.     STDMETHOD(f799)();
  1922.     STDMETHOD(f800)();
  1923.     STDMETHOD(f801)();
  1924.     STDMETHOD(f802)();
  1925.     STDMETHOD(f803)();
  1926.     STDMETHOD(f804)();
  1927.     STDMETHOD(f805)();
  1928.     STDMETHOD(f806)();
  1929.     STDMETHOD(f807)();
  1930.     STDMETHOD(f808)();
  1931.     STDMETHOD(f809)();
  1932.     STDMETHOD(f810)();
  1933.     STDMETHOD(f811)();
  1934.     STDMETHOD(f812)();
  1935.     STDMETHOD(f813)();
  1936.     STDMETHOD(f814)();
  1937.     STDMETHOD(f815)();
  1938.     STDMETHOD(f816)();
  1939.     STDMETHOD(f817)();
  1940.     STDMETHOD(f818)();
  1941.     STDMETHOD(f819)();
  1942.     STDMETHOD(f820)();
  1943.     STDMETHOD(f821)();
  1944.     STDMETHOD(f822)();
  1945.     STDMETHOD(f823)();
  1946.     STDMETHOD(f824)();
  1947.     STDMETHOD(f825)();
  1948.     STDMETHOD(f826)();
  1949.     STDMETHOD(f827)();
  1950.     STDMETHOD(f828)();
  1951.     STDMETHOD(f829)();
  1952.     STDMETHOD(f830)();
  1953.     STDMETHOD(f831)();
  1954.     STDMETHOD(f832)();
  1955.     STDMETHOD(f833)();
  1956.     STDMETHOD(f834)();
  1957.     STDMETHOD(f835)();
  1958.     STDMETHOD(f836)();
  1959.     STDMETHOD(f837)();
  1960.     STDMETHOD(f838)();
  1961.     STDMETHOD(f839)();
  1962.     STDMETHOD(f840)();
  1963.     STDMETHOD(f841)();
  1964.     STDMETHOD(f842)();
  1965.     STDMETHOD(f843)();
  1966.     STDMETHOD(f844)();
  1967.     STDMETHOD(f845)();
  1968.     STDMETHOD(f846)();
  1969.     STDMETHOD(f847)();
  1970.     STDMETHOD(f848)();
  1971.     STDMETHOD(f849)();
  1972.     STDMETHOD(f850)();
  1973.     STDMETHOD(f851)();
  1974.     STDMETHOD(f852)();
  1975.     STDMETHOD(f853)();
  1976.     STDMETHOD(f854)();
  1977.     STDMETHOD(f855)();
  1978.     STDMETHOD(f856)();
  1979.     STDMETHOD(f857)();
  1980.     STDMETHOD(f858)();
  1981.     STDMETHOD(f859)();
  1982.     STDMETHOD(f860)();
  1983.     STDMETHOD(f861)();
  1984.     STDMETHOD(f862)();
  1985.     STDMETHOD(f863)();
  1986.     STDMETHOD(f864)();
  1987.     STDMETHOD(f865)();
  1988.     STDMETHOD(f866)();
  1989.     STDMETHOD(f867)();
  1990.     STDMETHOD(f868)();
  1991.     STDMETHOD(f869)();
  1992.     STDMETHOD(f870)();
  1993.     STDMETHOD(f871)();
  1994.     STDMETHOD(f872)();
  1995.     STDMETHOD(f873)();
  1996.     STDMETHOD(f874)();
  1997.     STDMETHOD(f875)();
  1998.     STDMETHOD(f876)();
  1999.     STDMETHOD(f877)();
  2000.     STDMETHOD(f878)();
  2001.     STDMETHOD(f879)();
  2002.     STDMETHOD(f880)();
  2003.     STDMETHOD(f881)();
  2004.     STDMETHOD(f882)();
  2005.     STDMETHOD(f883)();
  2006.     STDMETHOD(f884)();
  2007.     STDMETHOD(f885)();
  2008.     STDMETHOD(f886)();
  2009.     STDMETHOD(f887)();
  2010.     STDMETHOD(f888)();
  2011.     STDMETHOD(f889)();
  2012.     STDMETHOD(f890)();
  2013.     STDMETHOD(f891)();
  2014.     STDMETHOD(f892)();
  2015.     STDMETHOD(f893)();
  2016.     STDMETHOD(f894)();
  2017.     STDMETHOD(f895)();
  2018.     STDMETHOD(f896)();
  2019.     STDMETHOD(f897)();
  2020.     STDMETHOD(f898)();
  2021.     STDMETHOD(f899)();
  2022.     STDMETHOD(f900)();
  2023.     STDMETHOD(f901)();
  2024.     STDMETHOD(f902)();
  2025.     STDMETHOD(f903)();
  2026.     STDMETHOD(f904)();
  2027.     STDMETHOD(f905)();
  2028.     STDMETHOD(f906)();
  2029.     STDMETHOD(f907)();
  2030.     STDMETHOD(f908)();
  2031.     STDMETHOD(f909)();
  2032.     STDMETHOD(f910)();
  2033.     STDMETHOD(f911)();
  2034.     STDMETHOD(f912)();
  2035.     STDMETHOD(f913)();
  2036.     STDMETHOD(f914)();
  2037.     STDMETHOD(f915)();
  2038.     STDMETHOD(f916)();
  2039.     STDMETHOD(f917)();
  2040.     STDMETHOD(f918)();
  2041.     STDMETHOD(f919)();
  2042.     STDMETHOD(f920)();
  2043.     STDMETHOD(f921)();
  2044.     STDMETHOD(f922)();
  2045.     STDMETHOD(f923)();
  2046.     STDMETHOD(f924)();
  2047.     STDMETHOD(f925)();
  2048.     STDMETHOD(f926)();
  2049.     STDMETHOD(f927)();
  2050.     STDMETHOD(f928)();
  2051.     STDMETHOD(f929)();
  2052.     STDMETHOD(f930)();
  2053.     STDMETHOD(f931)();
  2054.     STDMETHOD(f932)();
  2055.     STDMETHOD(f933)();
  2056.     STDMETHOD(f934)();
  2057.     STDMETHOD(f935)();
  2058.     STDMETHOD(f936)();
  2059.     STDMETHOD(f937)();
  2060.     STDMETHOD(f938)();
  2061.     STDMETHOD(f939)();
  2062.     STDMETHOD(f940)();
  2063.     STDMETHOD(f941)();
  2064.     STDMETHOD(f942)();
  2065.     STDMETHOD(f943)();
  2066.     STDMETHOD(f944)();
  2067.     STDMETHOD(f945)();
  2068.     STDMETHOD(f946)();
  2069.     STDMETHOD(f947)();
  2070.     STDMETHOD(f948)();
  2071.     STDMETHOD(f949)();
  2072.     STDMETHOD(f950)();
  2073.     STDMETHOD(f951)();
  2074.     STDMETHOD(f952)();
  2075.     STDMETHOD(f953)();
  2076.     STDMETHOD(f954)();
  2077.     STDMETHOD(f955)();
  2078.     STDMETHOD(f956)();
  2079.     STDMETHOD(f957)();
  2080.     STDMETHOD(f958)();
  2081.     STDMETHOD(f959)();
  2082.     STDMETHOD(f960)();
  2083.     STDMETHOD(f961)();
  2084.     STDMETHOD(f962)();
  2085.     STDMETHOD(f963)();
  2086.     STDMETHOD(f964)();
  2087.     STDMETHOD(f965)();
  2088.     STDMETHOD(f966)();
  2089.     STDMETHOD(f967)();
  2090.     STDMETHOD(f968)();
  2091.     STDMETHOD(f969)();
  2092.     STDMETHOD(f970)();
  2093.     STDMETHOD(f971)();
  2094.     STDMETHOD(f972)();
  2095.     STDMETHOD(f973)();
  2096.     STDMETHOD(f974)();
  2097.     STDMETHOD(f975)();
  2098.     STDMETHOD(f976)();
  2099.     STDMETHOD(f977)();
  2100.     STDMETHOD(f978)();
  2101.     STDMETHOD(f979)();
  2102.     STDMETHOD(f980)();
  2103.     STDMETHOD(f981)();
  2104.     STDMETHOD(f982)();
  2105.     STDMETHOD(f983)();
  2106.     STDMETHOD(f984)();
  2107.     STDMETHOD(f985)();
  2108.     STDMETHOD(f986)();
  2109.     STDMETHOD(f987)();
  2110.     STDMETHOD(f988)();
  2111.     STDMETHOD(f989)();
  2112.     STDMETHOD(f990)();
  2113.     STDMETHOD(f991)();
  2114.     STDMETHOD(f992)();
  2115.     STDMETHOD(f993)();
  2116.     STDMETHOD(f994)();
  2117.     STDMETHOD(f995)();
  2118.     STDMETHOD(f996)();
  2119.     STDMETHOD(f997)();
  2120.     STDMETHOD(f998)();
  2121.     STDMETHOD(f999)();
  2122.     STDMETHOD(f1000)();
  2123.     STDMETHOD(f1001)();
  2124.     STDMETHOD(f1002)();
  2125.     STDMETHOD(f1003)();
  2126.     STDMETHOD(f1004)();
  2127.     STDMETHOD(f1005)();
  2128.     STDMETHOD(f1006)();
  2129.     STDMETHOD(f1007)();
  2130.     STDMETHOD(f1008)();
  2131.     STDMETHOD(f1009)();
  2132.     STDMETHOD(f1010)();
  2133.     STDMETHOD(f1011)();
  2134.     STDMETHOD(f1012)();
  2135.     STDMETHOD(f1013)();
  2136.     STDMETHOD(f1014)();
  2137.     STDMETHOD(f1015)();
  2138.     STDMETHOD(f1016)();
  2139.     STDMETHOD(f1017)();
  2140.     STDMETHOD(f1018)();
  2141.     STDMETHOD(f1019)();
  2142.     STDMETHOD(f1020)();
  2143.     STDMETHOD(f1021)();
  2144.     STDMETHOD(f1022)();
  2145.     STDMETHOD(f1023)();
  2146.     STDMETHOD(f1024)();
  2147.     _QIThunk(IUnknown* pOrig, LPCTSTR p, const IID& i, UINT n, bool b)
  2148.     {
  2149.         lpszClassName = p;
  2150.         iid = i;
  2151.         nIndex = n;
  2152.         m_dwRef = 0;
  2153.         m_dwMaxRef = 0;
  2154.         pUnk = pOrig;
  2155.         bBreak = b;
  2156.         bNonAddRefThunk = false;
  2157.     }
  2158.     IUnknown* pUnk;
  2159.     long m_dwRef;
  2160.     long m_dwMaxRef;
  2161.     LPCTSTR lpszClassName;
  2162.     IID iid;
  2163.     UINT nIndex;
  2164.     bool bBreak;
  2165.     bool bNonAddRefThunk;
  2166.     void Dump()
  2167.     {
  2168.         TCHAR buf[256];
  2169.         if (m_dwRef != 0)
  2170.         {
  2171.             wsprintf(buf, _T("INTERFACE LEAK: RefCount = %d, MaxRefCount = %d, {Allocation = %d} "), m_dwRef, m_dwMaxRef, nIndex);
  2172.             OutputDebugString(buf);
  2173.             AtlDumpIID(iid, lpszClassName, S_OK);
  2174.         }
  2175.         else
  2176.         {
  2177.             wsprintf(buf, _T("NonAddRef Thunk LEAK: {Allocation = %d}\n"), nIndex);
  2178.             OutputDebugString(buf);
  2179.         }
  2180.     }
  2181. };
  2182. #endif
  2183.  
  2184.  
  2185. /////////////////////////////////////////////////////////////////////////////
  2186. // Collection helpers - CSimpleArray & CSimpleMap
  2187.  
  2188. template <class T>
  2189. class CSimpleArray
  2190. {
  2191. public:
  2192.     T* m_aT;
  2193.     int m_nSize;
  2194.     int m_nAllocSize;
  2195.  
  2196. // Construction/destruction
  2197.     CSimpleArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  2198.     { }
  2199.  
  2200.     ~CSimpleArray()
  2201.     {
  2202.         RemoveAll();
  2203.     }
  2204.  
  2205. // Operations
  2206.     int GetSize() const
  2207.     {
  2208.         return m_nSize;
  2209.     }
  2210.     BOOL Add(T& t)
  2211.     {
  2212.         if(m_nSize == m_nAllocSize)
  2213.         {
  2214.             T* aT;
  2215.             int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);
  2216.             aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));
  2217.             if(aT == NULL)
  2218.                 return FALSE;
  2219.             m_nAllocSize = nNewAllocSize;
  2220.             m_aT = aT;
  2221.         }
  2222.         m_nSize++;
  2223.         SetAtIndex(m_nSize - 1, t);
  2224.         return TRUE;
  2225.     }
  2226.     BOOL Remove(T& t)
  2227.     {
  2228.         int nIndex = Find(t);
  2229.         if(nIndex == -1)
  2230.             return FALSE;
  2231.         return RemoveAt(nIndex);
  2232.     }
  2233.     BOOL RemoveAt(int nIndex)
  2234.     {
  2235.         if(nIndex != (m_nSize - 1))
  2236.         {
  2237. #if (_WIN32_WCE == 200)
  2238.             if(m_aT[nIndex] != NULL)
  2239.                 delete m_aT[nIndex];
  2240. #else // _WIN32_WCE
  2241.             m_aT[nIndex].~T();
  2242. #endif // _WIN32_WCE
  2243.             memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T));
  2244.         }
  2245.         m_nSize--;
  2246.         return TRUE;
  2247.     }
  2248.     void RemoveAll()
  2249.     {
  2250.         if(m_aT != NULL)
  2251.         {
  2252.             for(int i = 0; i < m_nSize; i++)
  2253. #if (_WIN32_WCE == 200)
  2254.                 if(m_aT[i] != NULL)
  2255.                     delete m_aT[i];
  2256. #else // _WIN32_WCE
  2257.                 m_aT[i].~T();
  2258. #endif // _WIN32_WCE
  2259.             free(m_aT);
  2260.             m_aT = NULL;
  2261.         }
  2262.         m_nSize = 0;
  2263.         m_nAllocSize = 0;
  2264.     }
  2265.     T& operator[] (int nIndex) const
  2266.     {
  2267.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2268.         return m_aT[nIndex];
  2269.     }
  2270.     T* GetData() const
  2271.     {
  2272.         return m_aT;
  2273.     }
  2274.  
  2275. // Implementation
  2276.     class Wrapper
  2277.     {
  2278.     public:
  2279.         Wrapper(T& _t) : t(_t)
  2280.         {
  2281.         }
  2282.         template <class _Ty>
  2283.         void *operator new(size_t, _Ty* p)
  2284.         {
  2285.             return p;
  2286.         }
  2287.         T t;
  2288.     };
  2289.     void SetAtIndex(int nIndex, T& t)
  2290.     {
  2291.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2292.         new(&m_aT[nIndex]) Wrapper(t);
  2293.     }
  2294.     int Find(T& t) const
  2295.     {
  2296.         for(int i = 0; i < m_nSize; i++)
  2297.         {
  2298.             if(m_aT[i] == t)
  2299.                 return i;
  2300.         }
  2301.         return -1;    // not found
  2302.     }
  2303. };
  2304.  
  2305. // for arrays of simple types
  2306. template <class T>
  2307. class CSimpleValArray : public CSimpleArray< T >
  2308. {
  2309. public:
  2310.     BOOL Add(T t)
  2311.     {
  2312.         return CSimpleArray< T >::Add(t);
  2313.     }
  2314.     BOOL Remove(T t)
  2315.     {
  2316.         return CSimpleArray< T >::Remove(t);
  2317.     }
  2318.     T operator[] (int nIndex) const
  2319.     {
  2320.         return CSimpleArray< T >::operator[](nIndex);
  2321.     }
  2322. };
  2323.  
  2324.  
  2325. // intended for small number of simple types or pointers
  2326. template <class TKey, class TVal>
  2327. class CSimpleMap
  2328. {
  2329. public:
  2330.     TKey* m_aKey;
  2331.     TVal* m_aVal;
  2332.     int m_nSize;
  2333.  
  2334. // Construction/destruction
  2335.     CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  2336.     { }
  2337.  
  2338.     ~CSimpleMap()
  2339.     {
  2340.         RemoveAll();
  2341.     }
  2342.  
  2343. // Operations
  2344.     int GetSize() const
  2345.     {
  2346.         return m_nSize;
  2347.     }
  2348.     BOOL Add(TKey key, TVal val)
  2349.     {
  2350.         TKey* pKey;
  2351.         pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  2352.         if(pKey == NULL)
  2353.             return FALSE;
  2354.         m_aKey = pKey;
  2355.         TVal* pVal;
  2356.         pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  2357.         if(pVal == NULL)
  2358.             return FALSE;
  2359.         m_aVal = pVal;
  2360.         m_nSize++;
  2361.         SetAtIndex(m_nSize - 1, key, val);
  2362.         return TRUE;
  2363.     }
  2364.     BOOL Remove(TKey key)
  2365.     {
  2366.         int nIndex = FindKey(key);
  2367.         if(nIndex == -1)
  2368.             return FALSE;
  2369.         if(nIndex != (m_nSize - 1))
  2370.         {
  2371. #if (_WIN32_WCE == 200)
  2372.             if(m_aKey[nIndex] != NULL)
  2373.                 delete m_aKey[nIndex];
  2374.             if(m_aVal[nIndex] != NULL)
  2375.                 delete m_aVal[nIndex];
  2376. #else // _WIN32_WCE
  2377.             m_aKey[nIndex].~TKey();
  2378.             m_aVal[nIndex].~TVal();
  2379. #endif // _WIN32_WCE
  2380.             memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
  2381.             memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
  2382.         }
  2383.         TKey* pKey;
  2384.         pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  2385.         if(pKey != NULL || m_nSize == 1)
  2386.             m_aKey = pKey;
  2387.         TVal* pVal;
  2388.         pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  2389.         if(pVal != NULL || m_nSize == 1)
  2390.             m_aVal = pVal;
  2391.         m_nSize--;
  2392.         return TRUE;
  2393.     }
  2394.     void RemoveAll()
  2395.     {
  2396.         if(m_aKey != NULL)
  2397.         {
  2398.             for(int i = 0; i < m_nSize; i++)
  2399.             {
  2400. #if (_WIN32_WCE == 200)
  2401.             if(m_aKey[i] != NULL)
  2402.                 delete m_aKey[nIndex];
  2403.             if(m_aVal[i] != NULL)
  2404.                 delete m_aVal[nIndex];
  2405. #else // _WIN32_WCE
  2406.                 m_aKey[i].~TKey();
  2407.                 m_aVal[i].~TVal();
  2408. #endif // _WIN32_WCE
  2409.             }
  2410.             free(m_aKey);
  2411.             m_aKey = NULL;
  2412.         }
  2413.         if(m_aVal != NULL)
  2414.         {
  2415.             free(m_aVal);
  2416.             m_aVal = NULL;
  2417.         }
  2418.  
  2419.         m_nSize = 0;
  2420.     }
  2421.     BOOL SetAt(TKey key, TVal val)
  2422.     {
  2423.         int nIndex = FindKey(key);
  2424.         if(nIndex == -1)
  2425.             return FALSE;
  2426.         SetAtIndex(nIndex, key, val);
  2427.         return TRUE;
  2428.     }
  2429.     TVal Lookup(TKey key) const
  2430.     {
  2431.         int nIndex = FindKey(key);
  2432.         if(nIndex == -1)
  2433.             return NULL;    // must be able to convert
  2434.         return GetValueAt(nIndex);
  2435.     }
  2436.     TKey ReverseLookup(TVal val) const
  2437.     {
  2438.         int nIndex = FindVal(val);
  2439.         if(nIndex == -1)
  2440.             return NULL;    // must be able to convert
  2441.         return GetKeyAt(nIndex);
  2442.     }
  2443.     TKey& GetKeyAt(int nIndex) const
  2444.     {
  2445.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2446.         return m_aKey[nIndex];
  2447.     }
  2448.     TVal& GetValueAt(int nIndex) const
  2449.     {
  2450.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2451.         return m_aVal[nIndex];
  2452.     }
  2453.  
  2454. // Implementation
  2455.  
  2456.     template <typename T>
  2457.     class Wrapper
  2458.     {
  2459.     public:
  2460.         Wrapper(T& _t) : t(_t)
  2461.         {
  2462.         }
  2463.         template <typename _Ty>
  2464.         void *operator new(size_t, _Ty* p)
  2465.         {
  2466.             return p;
  2467.         }
  2468.         T t;
  2469.     };
  2470.     void SetAtIndex(int nIndex, TKey& key, TVal& val)
  2471.     {
  2472.         ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  2473.         new(&m_aKey[nIndex]) Wrapper<TKey>(key);
  2474.         new(&m_aVal[nIndex]) Wrapper<TVal>(val);
  2475.     }
  2476.     int FindKey(TKey& key) const
  2477.     {
  2478.         for(int i = 0; i < m_nSize; i++)
  2479.         {
  2480.             if(m_aKey[i] == key)
  2481.                 return i;
  2482.         }
  2483.         return -1;    // not found
  2484.     }
  2485.     int FindVal(TVal& val) const
  2486.     {
  2487.         for(int i = 0; i < m_nSize; i++)
  2488.         {
  2489.             if(m_aVal[i] == val)
  2490.                 return i;
  2491.         }
  2492.         return -1;    // not found
  2493.     }
  2494. };
  2495.  
  2496.  
  2497. class CComModule;
  2498. __declspec(selectany) CComModule* _pModule=NULL;
  2499.  
  2500. // {B62F5910-6528-11d1-9611-0000F81E0D0D}
  2501. _declspec(selectany) GUID GUID_ATLVer30 = { 0xb62f5910, 0x6528, 0x11d1, { 0x96, 0x11, 0x0, 0x0, 0xf8, 0x1e, 0xd, 0xd } };
  2502.  
  2503. class CComModule : public _ATL_MODULE
  2504. {
  2505. // Operations
  2506. public:
  2507.     static GUID m_libid;
  2508. #ifdef _ATL_DEBUG_INTERFACES
  2509.     UINT m_nIndexQI;
  2510.     UINT m_nIndexBreakAt;
  2511.     CSimpleArray<_QIThunk*>* m_paThunks;
  2512. #endif // _ATL_DEBUG_INTERFACES
  2513.  
  2514.     void AddCreateWndData(_AtlCreateWndData* pData, void* pObject)
  2515.     {
  2516.         AtlModuleAddCreateWndData(this, pData, pObject);
  2517.     }
  2518.     void* ExtractCreateWndData()
  2519.     {
  2520.         return AtlModuleExtractCreateWndData(this);
  2521.     }
  2522.  
  2523.     HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL)
  2524.     {
  2525.         pguidVer = &GUID_ATLVer30;
  2526.         _pModule = this;
  2527.         cbSize = sizeof(_ATL_MODULE);
  2528.         dwAtlBuildVer = _ATL_VER;
  2529.         AtlModuleInit(this, p, h);
  2530.         if (plibid != NULL)
  2531.             memcpy((void*)&m_libid, plibid, sizeof(GUID));
  2532. #ifdef _ATL_MIN_CRT
  2533.         // Create a base heap
  2534.         m_hHeap = HeapCreate(0, 0, 0);
  2535.  
  2536. #ifndef _ATL_NO_MP_HEAP
  2537.         SYSTEM_INFO si;
  2538.         GetSystemInfo(&si);
  2539.         if (si.dwNumberOfProcessors > 1)
  2540.         {
  2541.             DWORD dwHeaps = si.dwNumberOfProcessors * 2;
  2542.             m_dwHeaps = 0xFFFFFFFF;
  2543.             for (int bits=0; bits<32; bits++)
  2544.             {
  2545.                 if (dwHeaps & 0x80000000)
  2546.                     break;
  2547.                 dwHeaps <<= 1;
  2548.                 m_dwHeaps >>= 1;
  2549.             }
  2550.             m_dwHeaps >>= 1;
  2551.  
  2552.             // Allocate more heaps for each processor
  2553.             m_phHeaps = (HANDLE*) HeapAlloc(m_hHeap, _ATL_HEAPFLAGS, sizeof(HANDLE) * (m_dwHeaps + 1));
  2554.             for (DWORD i=0; i<=m_dwHeaps; i++)
  2555.                 m_phHeaps[i] = HeapCreate(0, 0, 0);
  2556.         }
  2557.         else
  2558. #endif
  2559.         {
  2560.             m_phHeaps = NULL;
  2561.             m_dwHeaps = 0;
  2562.         }
  2563. #endif
  2564. #ifdef _ATL_DEBUG_INTERFACES
  2565.         m_nIndexQI = 0;
  2566.         m_nIndexBreakAt = 0;
  2567.         m_paThunks = NULL;
  2568.         ATLTRY(m_paThunks = new CSimpleArray<_QIThunk*>);
  2569.         if (m_paThunks == NULL)
  2570.             return E_OUTOFMEMORY;
  2571. #endif // _ATL_DEBUG_INTERFACES
  2572.         return S_OK;
  2573.     }
  2574. #ifdef _ATL_DEBUG_INTERFACES
  2575.     HRESULT AddThunk(IUnknown** pp, LPCTSTR lpsz, REFIID iid)
  2576.     {
  2577.         if ((pp == NULL) || (*pp == NULL))
  2578.             return E_POINTER;
  2579.         IUnknown* p = *pp;
  2580.         _QIThunk* pThunk = NULL;
  2581.         EnterCriticalSection(&m_csObjMap);
  2582.         // Check if exists already for identity
  2583.         if (InlineIsEqualUnknown(iid))
  2584.         {
  2585.             for (int i=0; i<m_paThunks->GetSize(); i++)
  2586.             {
  2587.                 if (m_paThunks->operator[](i)->pUnk == p)
  2588.                 {
  2589.                     m_paThunks->operator[](i)->InternalAddRef();
  2590.                     pThunk = m_paThunks->operator[](i);
  2591.                     break;
  2592.                 }
  2593.             }
  2594.         }
  2595.         if (pThunk == NULL)
  2596.         {
  2597.             ++m_nIndexQI;
  2598.             if (m_nIndexBreakAt == m_nIndexQI)
  2599.                 DebugBreak();
  2600.             ATLTRY(pThunk = new _QIThunk(p, lpsz, iid, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
  2601.             if (pThunk == NULL)
  2602.                 return E_OUTOFMEMORY;
  2603.             pThunk->InternalAddRef();
  2604.             m_paThunks->Add(pThunk);
  2605.         }
  2606.         LeaveCriticalSection(&m_csObjMap);
  2607.         *pp = (IUnknown*)pThunk;
  2608.         return S_OK;
  2609.     }
  2610.     HRESULT AddNonAddRefThunk(IUnknown* p, LPCTSTR lpsz, IUnknown** ppThunkRet)
  2611.     {
  2612.         _QIThunk* pThunk = NULL;
  2613.         EnterCriticalSection(&m_csObjMap);
  2614.         // Check if exists already for identity
  2615.         for (int i=0; i<m_paThunks->GetSize(); i++)
  2616.         {
  2617.             if (m_paThunks->operator[](i)->pUnk == p)
  2618.             {
  2619.                 m_paThunks->operator[](i)->bNonAddRefThunk = true;
  2620.                 pThunk = m_paThunks->operator[](i);
  2621.                 break;
  2622.             }
  2623.         }
  2624.         if (pThunk == NULL)
  2625.         {
  2626.             ++m_nIndexQI;
  2627.             if (m_nIndexBreakAt == m_nIndexQI)
  2628.                 DebugBreak();
  2629.             ATLTRY(pThunk = new _QIThunk(p, lpsz, IID_IUnknown, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
  2630.             if (pThunk == NULL)
  2631.             {
  2632.                 *ppThunkRet = NULL;
  2633.                 return E_OUTOFMEMORY;
  2634.             }
  2635.             pThunk->bNonAddRefThunk = true;
  2636.             m_paThunks->Add(pThunk);
  2637.         }
  2638.         LeaveCriticalSection(&m_csObjMap);
  2639.         *ppThunkRet = (IUnknown*)pThunk;
  2640.         return S_OK;;
  2641.     }
  2642.     void DeleteNonAddRefThunk(IUnknown* pUnk)
  2643.     {
  2644.         EnterCriticalSection(&m_csObjMap);
  2645.         for (int i=0; i<m_paThunks->GetSize(); i++)
  2646.         {
  2647.             if (m_paThunks->operator[](i)->pUnk == pUnk)
  2648.             {
  2649.                 delete m_paThunks->operator[](i);
  2650.                 m_paThunks->RemoveAt(i);
  2651.                 break;
  2652.             }
  2653.         }
  2654.         LeaveCriticalSection(&m_csObjMap);
  2655.     }
  2656.     void DeleteThunk(_QIThunk* p)
  2657.     {
  2658.         EnterCriticalSection(&m_csObjMap);
  2659.         int nIndex = m_paThunks->Find(p);
  2660.         if (nIndex != -1)
  2661.         {
  2662.             delete m_paThunks->operator[](nIndex);
  2663.             m_paThunks->RemoveAt(nIndex);
  2664.         }
  2665.         LeaveCriticalSection(&m_csObjMap);
  2666.     }
  2667.     bool DumpLeakedThunks()
  2668.     {
  2669.         bool b = false;
  2670.         for (int i=0; i<m_paThunks->GetSize(); i++)
  2671.         {
  2672.             b = true;
  2673.             m_paThunks->operator[](i)->Dump();
  2674.             delete m_paThunks->operator[](i);
  2675.         }
  2676.         m_paThunks->RemoveAll();
  2677.         return b;
  2678.     }
  2679. #endif // _ATL_DEBUG_INTERFACES
  2680.     void Term()
  2681.     {
  2682. #ifdef _ATL_DEBUG_INTERFACES
  2683.         m_bDestroyHeap = false; // prevent heap from going away
  2684.         AtlModuleTerm(this);
  2685.         DumpLeakedThunks();
  2686.         delete m_paThunks;
  2687. #ifndef _ATL_NO_MP_HEAP
  2688.         if (m_phHeaps != NULL)
  2689.         {
  2690.             for (DWORD i = 0; i <= m_dwHeaps; i++)
  2691.                 HeapDestroy(m_phHeaps[i]);
  2692.         }
  2693. #endif
  2694.         if (m_hHeap != NULL)
  2695.             HeapDestroy(m_hHeap);
  2696. #else
  2697.         AtlModuleTerm(this);
  2698. #endif // _ATL_DEBUG_INTERFACES
  2699.     }
  2700.  
  2701.     HRESULT AddTermFunc(_ATL_TERMFUNC* pFunc, DWORD dw)
  2702.     {
  2703.         return AtlModuleAddTermFunc(this, pFunc, dw);
  2704.     }
  2705.  
  2706.     LONG Lock()
  2707.     {
  2708.         return CComGlobalsThreadModel::Increment(&m_nLockCnt);
  2709.     }
  2710.     LONG Unlock()
  2711.     {
  2712.         return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  2713.     }
  2714.     LONG GetLockCount()
  2715.     {
  2716.         return m_nLockCnt;
  2717.     }
  2718.  
  2719.     HINSTANCE GetModuleInstance() {return m_hInst;}
  2720.     HINSTANCE GetResourceInstance() {return m_hInstResource;}
  2721.     HINSTANCE GetTypeLibInstance() {return m_hInstTypeLib;}
  2722.  
  2723.     // Registry support (helpers)
  2724.     HRESULT RegisterTypeLib()
  2725.     {
  2726.         return AtlModuleRegisterTypeLib(this, NULL);
  2727.     }
  2728.     HRESULT RegisterTypeLib(LPCTSTR lpszIndex)
  2729.     {
  2730.         USES_CONVERSION;
  2731.         return AtlModuleRegisterTypeLib(this, T2COLE(lpszIndex));
  2732.     }
  2733.     HRESULT UnRegisterTypeLib()
  2734.     {
  2735.         return AtlModuleUnRegisterTypeLib(this, NULL);
  2736.     }
  2737.     HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex)
  2738.     {
  2739.         USES_CONVERSION;
  2740.         return AtlModuleUnRegisterTypeLib(this, T2COLE(lpszIndex));
  2741.     }
  2742.     HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
  2743.     {
  2744.         return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);
  2745.     }
  2746.  
  2747.     HRESULT UnregisterServer(const CLSID* pCLSID = NULL)
  2748.     {
  2749.         return AtlModuleUnregisterServer(this, pCLSID);
  2750.     }
  2751.     HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL)
  2752.     {
  2753.         return AtlModuleUnregisterServerEx(this, bUnRegTypeLib, pCLSID);
  2754.     }
  2755.  
  2756.     // Resource-based Registration
  2757.     HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
  2758.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  2759.     {
  2760.         USES_CONVERSION;
  2761.         return AtlModuleUpdateRegistryFromResourceD(this, T2COLE(lpszRes), bRegister,
  2762.             pMapEntries);
  2763.     }
  2764.     HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
  2765.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
  2766.     {
  2767.         return AtlModuleUpdateRegistryFromResourceD(this,
  2768.             (LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);
  2769.     }
  2770.  
  2771. #ifdef _ATL_STATIC_REGISTRY
  2772.     // Statically linking to Registry Ponent
  2773.     HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  2774.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  2775.     HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  2776.         struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
  2777. #endif
  2778.  
  2779.     // Standard Registration
  2780.     HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  2781.         LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);
  2782.     HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  2783.         LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags);
  2784.     HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  2785.         LPCTSTR lpszVerIndProgID);
  2786.  
  2787.     // Register/Revoke All Class Factories with the OS (EXE only)
  2788. #if !defined(_WIN32_WCE)
  2789.     HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags)
  2790.     {
  2791.         return AtlModuleRegisterClassObjects(this, dwClsContext, dwFlags);
  2792.     }
  2793.     HRESULT RevokeClassObjects()
  2794.     {
  2795.         return AtlModuleRevokeClassObjects(this);
  2796.     }
  2797. #endif // _WIN32_WCE
  2798.  
  2799.     // Obtain a Class Factory (DLL only)
  2800.     HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  2801.     {
  2802.         return AtlModuleGetClassObject(this, rclsid, riid, ppv);
  2803.     }
  2804.  
  2805.     // Only used in CComAutoThreadModule
  2806.     HRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/)
  2807.     {
  2808.         ATLASSERT(FALSE);
  2809.         return E_NOTIMPL;
  2810.     }
  2811.     static HRESULT RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc);
  2812.  
  2813.     static void ReplaceSingleQuote(LPOLESTR lpDest, LPCOLESTR lp)
  2814.     {
  2815.         while (*lp)
  2816.         {
  2817.             *lpDest++ = *lp;
  2818.             if (*lp == OLESTR('\''))
  2819.                 *lpDest++ = *lp;
  2820.             lp++;
  2821.         }
  2822.         *lpDest = NULL;
  2823.     }
  2824. };
  2825.  
  2826. #ifdef _ATL_DEBUG_INTERFACES
  2827. inline ULONG _QIThunk::Release()
  2828. {
  2829.     if (bBreak)
  2830.         DebugBreak();
  2831.     ATLASSERT(m_dwRef > 0);
  2832.     ULONG l = InterlockedDecrement(&m_dwRef);
  2833.     ATLTRACE(_T("%d< "), m_dwRef);
  2834.     AtlDumpIID(iid, lpszClassName, S_OK);
  2835.     pUnk->Release();
  2836.     if (l == 0 && !bNonAddRefThunk)
  2837.         _pModule->DeleteThunk(this);
  2838.     return l;
  2839. }
  2840. inline static void atlBadThunkCall()
  2841. {
  2842.     ATLASSERT(FALSE && "Call through deleted thunk");
  2843. }
  2844. #define IMPL_THUNK(n)\
  2845. __declspec(naked) inline HRESULT _QIThunk::f##n()\
  2846. {\
  2847.     __asm mov eax, [esp+4]\
  2848.     __asm cmp dword ptr [eax+8], 0\
  2849.     __asm jg goodref\
  2850.     __asm call atlBadThunkCall\
  2851.     __asm goodref:\
  2852.     __asm mov eax, [esp+4]\
  2853.     __asm mov eax, dword ptr [eax+4]\
  2854.     __asm mov [esp+4], eax\
  2855.     __asm mov eax, dword ptr [eax]\
  2856.     __asm mov eax, dword ptr [eax+4*n]\
  2857.     __asm jmp eax\
  2858. }
  2859.  
  2860. IMPL_THUNK(3)
  2861. IMPL_THUNK(4)
  2862. IMPL_THUNK(5)
  2863. IMPL_THUNK(6)
  2864. IMPL_THUNK(7)
  2865. IMPL_THUNK(8)
  2866. IMPL_THUNK(9)
  2867. IMPL_THUNK(10)
  2868. IMPL_THUNK(11)
  2869. IMPL_THUNK(12)
  2870. IMPL_THUNK(13)
  2871. IMPL_THUNK(14)
  2872. IMPL_THUNK(15)
  2873. IMPL_THUNK(16)
  2874. IMPL_THUNK(17)
  2875. IMPL_THUNK(18)
  2876. IMPL_THUNK(19)
  2877. IMPL_THUNK(20)
  2878. IMPL_THUNK(21)
  2879. IMPL_THUNK(22)
  2880. IMPL_THUNK(23)
  2881. IMPL_THUNK(24)
  2882. IMPL_THUNK(25)
  2883. IMPL_THUNK(26)
  2884. IMPL_THUNK(27)
  2885. IMPL_THUNK(28)
  2886. IMPL_THUNK(29)
  2887. IMPL_THUNK(30)
  2888. IMPL_THUNK(31)
  2889. IMPL_THUNK(32)
  2890. IMPL_THUNK(33)
  2891. IMPL_THUNK(34)
  2892. IMPL_THUNK(35)
  2893. IMPL_THUNK(36)
  2894. IMPL_THUNK(37)
  2895. IMPL_THUNK(38)
  2896. IMPL_THUNK(39)
  2897. IMPL_THUNK(40)
  2898. IMPL_THUNK(41)
  2899. IMPL_THUNK(42)
  2900. IMPL_THUNK(43)
  2901. IMPL_THUNK(44)
  2902. IMPL_THUNK(45)
  2903. IMPL_THUNK(46)
  2904. IMPL_THUNK(47)
  2905. IMPL_THUNK(48)
  2906. IMPL_THUNK(49)
  2907. IMPL_THUNK(50)
  2908. IMPL_THUNK(51)
  2909. IMPL_THUNK(52)
  2910. IMPL_THUNK(53)
  2911. IMPL_THUNK(54)
  2912. IMPL_THUNK(55)
  2913. IMPL_THUNK(56)
  2914. IMPL_THUNK(57)
  2915. IMPL_THUNK(58)
  2916. IMPL_THUNK(59)
  2917. IMPL_THUNK(60)
  2918. IMPL_THUNK(61)
  2919. IMPL_THUNK(62)
  2920. IMPL_THUNK(63)
  2921. IMPL_THUNK(64)
  2922. IMPL_THUNK(65)
  2923. IMPL_THUNK(66)
  2924. IMPL_THUNK(67)
  2925. IMPL_THUNK(68)
  2926. IMPL_THUNK(69)
  2927. IMPL_THUNK(70)
  2928. IMPL_THUNK(71)
  2929. IMPL_THUNK(72)
  2930. IMPL_THUNK(73)
  2931. IMPL_THUNK(74)
  2932. IMPL_THUNK(75)
  2933. IMPL_THUNK(76)
  2934. IMPL_THUNK(77)
  2935. IMPL_THUNK(78)
  2936. IMPL_THUNK(79)
  2937. IMPL_THUNK(80)
  2938. IMPL_THUNK(81)
  2939. IMPL_THUNK(82)
  2940. IMPL_THUNK(83)
  2941. IMPL_THUNK(84)
  2942. IMPL_THUNK(85)
  2943. IMPL_THUNK(86)
  2944. IMPL_THUNK(87)
  2945. IMPL_THUNK(88)
  2946. IMPL_THUNK(89)
  2947. IMPL_THUNK(90)
  2948. IMPL_THUNK(91)
  2949. IMPL_THUNK(92)
  2950. IMPL_THUNK(93)
  2951. IMPL_THUNK(94)
  2952. IMPL_THUNK(95)
  2953. IMPL_THUNK(96)
  2954. IMPL_THUNK(97)
  2955. IMPL_THUNK(98)
  2956. IMPL_THUNK(99)
  2957. IMPL_THUNK(100)
  2958. IMPL_THUNK(101)
  2959. IMPL_THUNK(102)
  2960. IMPL_THUNK(103)
  2961. IMPL_THUNK(104)
  2962. IMPL_THUNK(105)
  2963. IMPL_THUNK(106)
  2964. IMPL_THUNK(107)
  2965. IMPL_THUNK(108)
  2966. IMPL_THUNK(109)
  2967. IMPL_THUNK(110)
  2968. IMPL_THUNK(111)
  2969. IMPL_THUNK(112)
  2970. IMPL_THUNK(113)
  2971. IMPL_THUNK(114)
  2972. IMPL_THUNK(115)
  2973. IMPL_THUNK(116)
  2974. IMPL_THUNK(117)
  2975. IMPL_THUNK(118)
  2976. IMPL_THUNK(119)
  2977. IMPL_THUNK(120)
  2978. IMPL_THUNK(121)
  2979. IMPL_THUNK(122)
  2980. IMPL_THUNK(123)
  2981. IMPL_THUNK(124)
  2982. IMPL_THUNK(125)
  2983. IMPL_THUNK(126)
  2984. IMPL_THUNK(127)
  2985. IMPL_THUNK(128)
  2986. IMPL_THUNK(129)
  2987. IMPL_THUNK(130)
  2988. IMPL_THUNK(131)
  2989. IMPL_THUNK(132)
  2990. IMPL_THUNK(133)
  2991. IMPL_THUNK(134)
  2992. IMPL_THUNK(135)
  2993. IMPL_THUNK(136)
  2994. IMPL_THUNK(137)
  2995. IMPL_THUNK(138)
  2996. IMPL_THUNK(139)
  2997. IMPL_THUNK(140)
  2998. IMPL_THUNK(141)
  2999. IMPL_THUNK(142)
  3000. IMPL_THUNK(143)
  3001. IMPL_THUNK(144)
  3002. IMPL_THUNK(145)
  3003. IMPL_THUNK(146)
  3004. IMPL_THUNK(147)
  3005. IMPL_THUNK(148)
  3006. IMPL_THUNK(149)
  3007. IMPL_THUNK(150)
  3008. IMPL_THUNK(151)
  3009. IMPL_THUNK(152)
  3010. IMPL_THUNK(153)
  3011. IMPL_THUNK(154)
  3012. IMPL_THUNK(155)
  3013. IMPL_THUNK(156)
  3014. IMPL_THUNK(157)
  3015. IMPL_THUNK(158)
  3016. IMPL_THUNK(159)
  3017. IMPL_THUNK(160)
  3018. IMPL_THUNK(161)
  3019. IMPL_THUNK(162)
  3020. IMPL_THUNK(163)
  3021. IMPL_THUNK(164)
  3022. IMPL_THUNK(165)
  3023. IMPL_THUNK(166)
  3024. IMPL_THUNK(167)
  3025. IMPL_THUNK(168)
  3026. IMPL_THUNK(169)
  3027. IMPL_THUNK(170)
  3028. IMPL_THUNK(171)
  3029. IMPL_THUNK(172)
  3030. IMPL_THUNK(173)
  3031. IMPL_THUNK(174)
  3032. IMPL_THUNK(175)
  3033. IMPL_THUNK(176)
  3034. IMPL_THUNK(177)
  3035. IMPL_THUNK(178)
  3036. IMPL_THUNK(179)
  3037. IMPL_THUNK(180)
  3038. IMPL_THUNK(181)
  3039. IMPL_THUNK(182)
  3040. IMPL_THUNK(183)
  3041. IMPL_THUNK(184)
  3042. IMPL_THUNK(185)
  3043. IMPL_THUNK(186)
  3044. IMPL_THUNK(187)
  3045. IMPL_THUNK(188)
  3046. IMPL_THUNK(189)
  3047. IMPL_THUNK(190)
  3048. IMPL_THUNK(191)
  3049. IMPL_THUNK(192)
  3050. IMPL_THUNK(193)
  3051. IMPL_THUNK(194)
  3052. IMPL_THUNK(195)
  3053. IMPL_THUNK(196)
  3054. IMPL_THUNK(197)
  3055. IMPL_THUNK(198)
  3056. IMPL_THUNK(199)
  3057. IMPL_THUNK(200)
  3058. IMPL_THUNK(201)
  3059. IMPL_THUNK(202)
  3060. IMPL_THUNK(203)
  3061. IMPL_THUNK(204)
  3062. IMPL_THUNK(205)
  3063. IMPL_THUNK(206)
  3064. IMPL_THUNK(207)
  3065. IMPL_THUNK(208)
  3066. IMPL_THUNK(209)
  3067. IMPL_THUNK(210)
  3068. IMPL_THUNK(211)
  3069. IMPL_THUNK(212)
  3070. IMPL_THUNK(213)
  3071. IMPL_THUNK(214)
  3072. IMPL_THUNK(215)
  3073. IMPL_THUNK(216)
  3074. IMPL_THUNK(217)
  3075. IMPL_THUNK(218)
  3076. IMPL_THUNK(219)
  3077. IMPL_THUNK(220)
  3078. IMPL_THUNK(221)
  3079. IMPL_THUNK(222)
  3080. IMPL_THUNK(223)
  3081. IMPL_THUNK(224)
  3082. IMPL_THUNK(225)
  3083. IMPL_THUNK(226)
  3084. IMPL_THUNK(227)
  3085. IMPL_THUNK(228)
  3086. IMPL_THUNK(229)
  3087. IMPL_THUNK(230)
  3088. IMPL_THUNK(231)
  3089. IMPL_THUNK(232)
  3090. IMPL_THUNK(233)
  3091. IMPL_THUNK(234)
  3092. IMPL_THUNK(235)
  3093. IMPL_THUNK(236)
  3094. IMPL_THUNK(237)
  3095. IMPL_THUNK(238)
  3096. IMPL_THUNK(239)
  3097. IMPL_THUNK(240)
  3098. IMPL_THUNK(241)
  3099. IMPL_THUNK(242)
  3100. IMPL_THUNK(243)
  3101. IMPL_THUNK(244)
  3102. IMPL_THUNK(245)
  3103. IMPL_THUNK(246)
  3104. IMPL_THUNK(247)
  3105. IMPL_THUNK(248)
  3106. IMPL_THUNK(249)
  3107. IMPL_THUNK(250)
  3108. IMPL_THUNK(251)
  3109. IMPL_THUNK(252)
  3110. IMPL_THUNK(253)
  3111. IMPL_THUNK(254)
  3112. IMPL_THUNK(255)
  3113. IMPL_THUNK(256)
  3114. IMPL_THUNK(257)
  3115. IMPL_THUNK(258)
  3116. IMPL_THUNK(259)
  3117. IMPL_THUNK(260)
  3118. IMPL_THUNK(261)
  3119. IMPL_THUNK(262)
  3120. IMPL_THUNK(263)
  3121. IMPL_THUNK(264)
  3122. IMPL_THUNK(265)
  3123. IMPL_THUNK(266)
  3124. IMPL_THUNK(267)
  3125. IMPL_THUNK(268)
  3126. IMPL_THUNK(269)
  3127. IMPL_THUNK(270)
  3128. IMPL_THUNK(271)
  3129. IMPL_THUNK(272)
  3130. IMPL_THUNK(273)
  3131. IMPL_THUNK(274)
  3132. IMPL_THUNK(275)
  3133. IMPL_THUNK(276)
  3134. IMPL_THUNK(277)
  3135. IMPL_THUNK(278)
  3136. IMPL_THUNK(279)
  3137. IMPL_THUNK(280)
  3138. IMPL_THUNK(281)
  3139. IMPL_THUNK(282)
  3140. IMPL_THUNK(283)
  3141. IMPL_THUNK(284)
  3142. IMPL_THUNK(285)
  3143. IMPL_THUNK(286)
  3144. IMPL_THUNK(287)
  3145. IMPL_THUNK(288)
  3146. IMPL_THUNK(289)
  3147. IMPL_THUNK(290)
  3148. IMPL_THUNK(291)
  3149. IMPL_THUNK(292)
  3150. IMPL_THUNK(293)
  3151. IMPL_THUNK(294)
  3152. IMPL_THUNK(295)
  3153. IMPL_THUNK(296)
  3154. IMPL_THUNK(297)
  3155. IMPL_THUNK(298)
  3156. IMPL_THUNK(299)
  3157. IMPL_THUNK(300)
  3158. IMPL_THUNK(301)
  3159. IMPL_THUNK(302)
  3160. IMPL_THUNK(303)
  3161. IMPL_THUNK(304)
  3162. IMPL_THUNK(305)
  3163. IMPL_THUNK(306)
  3164. IMPL_THUNK(307)
  3165. IMPL_THUNK(308)
  3166. IMPL_THUNK(309)
  3167. IMPL_THUNK(310)
  3168. IMPL_THUNK(311)
  3169. IMPL_THUNK(312)
  3170. IMPL_THUNK(313)
  3171. IMPL_THUNK(314)
  3172. IMPL_THUNK(315)
  3173. IMPL_THUNK(316)
  3174. IMPL_THUNK(317)
  3175. IMPL_THUNK(318)
  3176. IMPL_THUNK(319)
  3177. IMPL_THUNK(320)
  3178. IMPL_THUNK(321)
  3179. IMPL_THUNK(322)
  3180. IMPL_THUNK(323)
  3181. IMPL_THUNK(324)
  3182. IMPL_THUNK(325)
  3183. IMPL_THUNK(326)
  3184. IMPL_THUNK(327)
  3185. IMPL_THUNK(328)
  3186. IMPL_THUNK(329)
  3187. IMPL_THUNK(330)
  3188. IMPL_THUNK(331)
  3189. IMPL_THUNK(332)
  3190. IMPL_THUNK(333)
  3191. IMPL_THUNK(334)
  3192. IMPL_THUNK(335)
  3193. IMPL_THUNK(336)
  3194. IMPL_THUNK(337)
  3195. IMPL_THUNK(338)
  3196. IMPL_THUNK(339)
  3197. IMPL_THUNK(340)
  3198. IMPL_THUNK(341)
  3199. IMPL_THUNK(342)
  3200. IMPL_THUNK(343)
  3201. IMPL_THUNK(344)
  3202. IMPL_THUNK(345)
  3203. IMPL_THUNK(346)
  3204. IMPL_THUNK(347)
  3205. IMPL_THUNK(348)
  3206. IMPL_THUNK(349)
  3207. IMPL_THUNK(350)
  3208. IMPL_THUNK(351)
  3209. IMPL_THUNK(352)
  3210. IMPL_THUNK(353)
  3211. IMPL_THUNK(354)
  3212. IMPL_THUNK(355)
  3213. IMPL_THUNK(356)
  3214. IMPL_THUNK(357)
  3215. IMPL_THUNK(358)
  3216. IMPL_THUNK(359)
  3217. IMPL_THUNK(360)
  3218. IMPL_THUNK(361)
  3219. IMPL_THUNK(362)
  3220. IMPL_THUNK(363)
  3221. IMPL_THUNK(364)
  3222. IMPL_THUNK(365)
  3223. IMPL_THUNK(366)
  3224. IMPL_THUNK(367)
  3225. IMPL_THUNK(368)
  3226. IMPL_THUNK(369)
  3227. IMPL_THUNK(370)
  3228. IMPL_THUNK(371)
  3229. IMPL_THUNK(372)
  3230. IMPL_THUNK(373)
  3231. IMPL_THUNK(374)
  3232. IMPL_THUNK(375)
  3233. IMPL_THUNK(376)
  3234. IMPL_THUNK(377)
  3235. IMPL_THUNK(378)
  3236. IMPL_THUNK(379)
  3237. IMPL_THUNK(380)
  3238. IMPL_THUNK(381)
  3239. IMPL_THUNK(382)
  3240. IMPL_THUNK(383)
  3241. IMPL_THUNK(384)
  3242. IMPL_THUNK(385)
  3243. IMPL_THUNK(386)
  3244. IMPL_THUNK(387)
  3245. IMPL_THUNK(388)
  3246. IMPL_THUNK(389)
  3247. IMPL_THUNK(390)
  3248. IMPL_THUNK(391)
  3249. IMPL_THUNK(392)
  3250. IMPL_THUNK(393)
  3251. IMPL_THUNK(394)
  3252. IMPL_THUNK(395)
  3253. IMPL_THUNK(396)
  3254. IMPL_THUNK(397)
  3255. IMPL_THUNK(398)
  3256. IMPL_THUNK(399)
  3257. IMPL_THUNK(400)
  3258. IMPL_THUNK(401)
  3259. IMPL_THUNK(402)
  3260. IMPL_THUNK(403)
  3261. IMPL_THUNK(404)
  3262. IMPL_THUNK(405)
  3263. IMPL_THUNK(406)
  3264. IMPL_THUNK(407)
  3265. IMPL_THUNK(408)
  3266. IMPL_THUNK(409)
  3267. IMPL_THUNK(410)
  3268. IMPL_THUNK(411)
  3269. IMPL_THUNK(412)
  3270. IMPL_THUNK(413)
  3271. IMPL_THUNK(414)
  3272. IMPL_THUNK(415)
  3273. IMPL_THUNK(416)
  3274. IMPL_THUNK(417)
  3275. IMPL_THUNK(418)
  3276. IMPL_THUNK(419)
  3277. IMPL_THUNK(420)
  3278. IMPL_THUNK(421)
  3279. IMPL_THUNK(422)
  3280. IMPL_THUNK(423)
  3281. IMPL_THUNK(424)
  3282. IMPL_THUNK(425)
  3283. IMPL_THUNK(426)
  3284. IMPL_THUNK(427)
  3285. IMPL_THUNK(428)
  3286. IMPL_THUNK(429)
  3287. IMPL_THUNK(430)
  3288. IMPL_THUNK(431)
  3289. IMPL_THUNK(432)
  3290. IMPL_THUNK(433)
  3291. IMPL_THUNK(434)
  3292. IMPL_THUNK(435)
  3293. IMPL_THUNK(436)
  3294. IMPL_THUNK(437)
  3295. IMPL_THUNK(438)
  3296. IMPL_THUNK(439)
  3297. IMPL_THUNK(440)
  3298. IMPL_THUNK(441)
  3299. IMPL_THUNK(442)
  3300. IMPL_THUNK(443)
  3301. IMPL_THUNK(444)
  3302. IMPL_THUNK(445)
  3303. IMPL_THUNK(446)
  3304. IMPL_THUNK(447)
  3305. IMPL_THUNK(448)
  3306. IMPL_THUNK(449)
  3307. IMPL_THUNK(450)
  3308. IMPL_THUNK(451)
  3309. IMPL_THUNK(452)
  3310. IMPL_THUNK(453)
  3311. IMPL_THUNK(454)
  3312. IMPL_THUNK(455)
  3313. IMPL_THUNK(456)
  3314. IMPL_THUNK(457)
  3315. IMPL_THUNK(458)
  3316. IMPL_THUNK(459)
  3317. IMPL_THUNK(460)
  3318. IMPL_THUNK(461)
  3319. IMPL_THUNK(462)
  3320. IMPL_THUNK(463)
  3321. IMPL_THUNK(464)
  3322. IMPL_THUNK(465)
  3323. IMPL_THUNK(466)
  3324. IMPL_THUNK(467)
  3325. IMPL_THUNK(468)
  3326. IMPL_THUNK(469)
  3327. IMPL_THUNK(470)
  3328. IMPL_THUNK(471)
  3329. IMPL_THUNK(472)
  3330. IMPL_THUNK(473)
  3331. IMPL_THUNK(474)
  3332. IMPL_THUNK(475)
  3333. IMPL_THUNK(476)
  3334. IMPL_THUNK(477)
  3335. IMPL_THUNK(478)
  3336. IMPL_THUNK(479)
  3337. IMPL_THUNK(480)
  3338. IMPL_THUNK(481)
  3339. IMPL_THUNK(482)
  3340. IMPL_THUNK(483)
  3341. IMPL_THUNK(484)
  3342. IMPL_THUNK(485)
  3343. IMPL_THUNK(486)
  3344. IMPL_THUNK(487)
  3345. IMPL_THUNK(488)
  3346. IMPL_THUNK(489)
  3347. IMPL_THUNK(490)
  3348. IMPL_THUNK(491)
  3349. IMPL_THUNK(492)
  3350. IMPL_THUNK(493)
  3351. IMPL_THUNK(494)
  3352. IMPL_THUNK(495)
  3353. IMPL_THUNK(496)
  3354. IMPL_THUNK(497)
  3355. IMPL_THUNK(498)
  3356. IMPL_THUNK(499)
  3357. IMPL_THUNK(500)
  3358. IMPL_THUNK(501)
  3359. IMPL_THUNK(502)
  3360. IMPL_THUNK(503)
  3361. IMPL_THUNK(504)
  3362. IMPL_THUNK(505)
  3363. IMPL_THUNK(506)
  3364. IMPL_THUNK(507)
  3365. IMPL_THUNK(508)
  3366. IMPL_THUNK(509)
  3367. IMPL_THUNK(510)
  3368. IMPL_THUNK(511)
  3369. IMPL_THUNK(512)
  3370. IMPL_THUNK(513)
  3371. IMPL_THUNK(514)
  3372. IMPL_THUNK(515)
  3373. IMPL_THUNK(516)
  3374. IMPL_THUNK(517)
  3375. IMPL_THUNK(518)
  3376. IMPL_THUNK(519)
  3377. IMPL_THUNK(520)
  3378. IMPL_THUNK(521)
  3379. IMPL_THUNK(522)
  3380. IMPL_THUNK(523)
  3381. IMPL_THUNK(524)
  3382. IMPL_THUNK(525)
  3383. IMPL_THUNK(526)
  3384. IMPL_THUNK(527)
  3385. IMPL_THUNK(528)
  3386. IMPL_THUNK(529)
  3387. IMPL_THUNK(530)
  3388. IMPL_THUNK(531)
  3389. IMPL_THUNK(532)
  3390. IMPL_THUNK(533)
  3391. IMPL_THUNK(534)
  3392. IMPL_THUNK(535)
  3393. IMPL_THUNK(536)
  3394. IMPL_THUNK(537)
  3395. IMPL_THUNK(538)
  3396. IMPL_THUNK(539)
  3397. IMPL_THUNK(540)
  3398. IMPL_THUNK(541)
  3399. IMPL_THUNK(542)
  3400. IMPL_THUNK(543)
  3401. IMPL_THUNK(544)
  3402. IMPL_THUNK(545)
  3403. IMPL_THUNK(546)
  3404. IMPL_THUNK(547)
  3405. IMPL_THUNK(548)
  3406. IMPL_THUNK(549)
  3407. IMPL_THUNK(550)
  3408. IMPL_THUNK(551)
  3409. IMPL_THUNK(552)
  3410. IMPL_THUNK(553)
  3411. IMPL_THUNK(554)
  3412. IMPL_THUNK(555)
  3413. IMPL_THUNK(556)
  3414. IMPL_THUNK(557)
  3415. IMPL_THUNK(558)
  3416. IMPL_THUNK(559)
  3417. IMPL_THUNK(560)
  3418. IMPL_THUNK(561)
  3419. IMPL_THUNK(562)
  3420. IMPL_THUNK(563)
  3421. IMPL_THUNK(564)
  3422. IMPL_THUNK(565)
  3423. IMPL_THUNK(566)
  3424. IMPL_THUNK(567)
  3425. IMPL_THUNK(568)
  3426. IMPL_THUNK(569)
  3427. IMPL_THUNK(570)
  3428. IMPL_THUNK(571)
  3429. IMPL_THUNK(572)
  3430. IMPL_THUNK(573)
  3431. IMPL_THUNK(574)
  3432. IMPL_THUNK(575)
  3433. IMPL_THUNK(576)
  3434. IMPL_THUNK(577)
  3435. IMPL_THUNK(578)
  3436. IMPL_THUNK(579)
  3437. IMPL_THUNK(580)
  3438. IMPL_THUNK(581)
  3439. IMPL_THUNK(582)
  3440. IMPL_THUNK(583)
  3441. IMPL_THUNK(584)
  3442. IMPL_THUNK(585)
  3443. IMPL_THUNK(586)
  3444. IMPL_THUNK(587)
  3445. IMPL_THUNK(588)
  3446. IMPL_THUNK(589)
  3447. IMPL_THUNK(590)
  3448. IMPL_THUNK(591)
  3449. IMPL_THUNK(592)
  3450. IMPL_THUNK(593)
  3451. IMPL_THUNK(594)
  3452. IMPL_THUNK(595)
  3453. IMPL_THUNK(596)
  3454. IMPL_THUNK(597)
  3455. IMPL_THUNK(598)
  3456. IMPL_THUNK(599)
  3457. IMPL_THUNK(600)
  3458. IMPL_THUNK(601)
  3459. IMPL_THUNK(602)
  3460. IMPL_THUNK(603)
  3461. IMPL_THUNK(604)
  3462. IMPL_THUNK(605)
  3463. IMPL_THUNK(606)
  3464. IMPL_THUNK(607)
  3465. IMPL_THUNK(608)
  3466. IMPL_THUNK(609)
  3467. IMPL_THUNK(610)
  3468. IMPL_THUNK(611)
  3469. IMPL_THUNK(612)
  3470. IMPL_THUNK(613)
  3471. IMPL_THUNK(614)
  3472. IMPL_THUNK(615)
  3473. IMPL_THUNK(616)
  3474. IMPL_THUNK(617)
  3475. IMPL_THUNK(618)
  3476. IMPL_THUNK(619)
  3477. IMPL_THUNK(620)
  3478. IMPL_THUNK(621)
  3479. IMPL_THUNK(622)
  3480. IMPL_THUNK(623)
  3481. IMPL_THUNK(624)
  3482. IMPL_THUNK(625)
  3483. IMPL_THUNK(626)
  3484. IMPL_THUNK(627)
  3485. IMPL_THUNK(628)
  3486. IMPL_THUNK(629)
  3487. IMPL_THUNK(630)
  3488. IMPL_THUNK(631)
  3489. IMPL_THUNK(632)
  3490. IMPL_THUNK(633)
  3491. IMPL_THUNK(634)
  3492. IMPL_THUNK(635)
  3493. IMPL_THUNK(636)
  3494. IMPL_THUNK(637)
  3495. IMPL_THUNK(638)
  3496. IMPL_THUNK(639)
  3497. IMPL_THUNK(640)
  3498. IMPL_THUNK(641)
  3499. IMPL_THUNK(642)
  3500. IMPL_THUNK(643)
  3501. IMPL_THUNK(644)
  3502. IMPL_THUNK(645)
  3503. IMPL_THUNK(646)
  3504. IMPL_THUNK(647)
  3505. IMPL_THUNK(648)
  3506. IMPL_THUNK(649)
  3507. IMPL_THUNK(650)
  3508. IMPL_THUNK(651)
  3509. IMPL_THUNK(652)
  3510. IMPL_THUNK(653)
  3511. IMPL_THUNK(654)
  3512. IMPL_THUNK(655)
  3513. IMPL_THUNK(656)
  3514. IMPL_THUNK(657)
  3515. IMPL_THUNK(658)
  3516. IMPL_THUNK(659)
  3517. IMPL_THUNK(660)
  3518. IMPL_THUNK(661)
  3519. IMPL_THUNK(662)
  3520. IMPL_THUNK(663)
  3521. IMPL_THUNK(664)
  3522. IMPL_THUNK(665)
  3523. IMPL_THUNK(666)
  3524. IMPL_THUNK(667)
  3525. IMPL_THUNK(668)
  3526. IMPL_THUNK(669)
  3527. IMPL_THUNK(670)
  3528. IMPL_THUNK(671)
  3529. IMPL_THUNK(672)
  3530. IMPL_THUNK(673)
  3531. IMPL_THUNK(674)
  3532. IMPL_THUNK(675)
  3533. IMPL_THUNK(676)
  3534. IMPL_THUNK(677)
  3535. IMPL_THUNK(678)
  3536. IMPL_THUNK(679)
  3537. IMPL_THUNK(680)
  3538. IMPL_THUNK(681)
  3539. IMPL_THUNK(682)
  3540. IMPL_THUNK(683)
  3541. IMPL_THUNK(684)
  3542. IMPL_THUNK(685)
  3543. IMPL_THUNK(686)
  3544. IMPL_THUNK(687)
  3545. IMPL_THUNK(688)
  3546. IMPL_THUNK(689)
  3547. IMPL_THUNK(690)
  3548. IMPL_THUNK(691)
  3549. IMPL_THUNK(692)
  3550. IMPL_THUNK(693)
  3551. IMPL_THUNK(694)
  3552. IMPL_THUNK(695)
  3553. IMPL_THUNK(696)
  3554. IMPL_THUNK(697)
  3555. IMPL_THUNK(698)
  3556. IMPL_THUNK(699)
  3557. IMPL_THUNK(700)
  3558. IMPL_THUNK(701)
  3559. IMPL_THUNK(702)
  3560. IMPL_THUNK(703)
  3561. IMPL_THUNK(704)
  3562. IMPL_THUNK(705)
  3563. IMPL_THUNK(706)
  3564. IMPL_THUNK(707)
  3565. IMPL_THUNK(708)
  3566. IMPL_THUNK(709)
  3567. IMPL_THUNK(710)
  3568. IMPL_THUNK(711)
  3569. IMPL_THUNK(712)
  3570. IMPL_THUNK(713)
  3571. IMPL_THUNK(714)
  3572. IMPL_THUNK(715)
  3573. IMPL_THUNK(716)
  3574. IMPL_THUNK(717)
  3575. IMPL_THUNK(718)
  3576. IMPL_THUNK(719)
  3577. IMPL_THUNK(720)
  3578. IMPL_THUNK(721)
  3579. IMPL_THUNK(722)
  3580. IMPL_THUNK(723)
  3581. IMPL_THUNK(724)
  3582. IMPL_THUNK(725)
  3583. IMPL_THUNK(726)
  3584. IMPL_THUNK(727)
  3585. IMPL_THUNK(728)
  3586. IMPL_THUNK(729)
  3587. IMPL_THUNK(730)
  3588. IMPL_THUNK(731)
  3589. IMPL_THUNK(732)
  3590. IMPL_THUNK(733)
  3591. IMPL_THUNK(734)
  3592. IMPL_THUNK(735)
  3593. IMPL_THUNK(736)
  3594. IMPL_THUNK(737)
  3595. IMPL_THUNK(738)
  3596. IMPL_THUNK(739)
  3597. IMPL_THUNK(740)
  3598. IMPL_THUNK(741)
  3599. IMPL_THUNK(742)
  3600. IMPL_THUNK(743)
  3601. IMPL_THUNK(744)
  3602. IMPL_THUNK(745)
  3603. IMPL_THUNK(746)
  3604. IMPL_THUNK(747)
  3605. IMPL_THUNK(748)
  3606. IMPL_THUNK(749)
  3607. IMPL_THUNK(750)
  3608. IMPL_THUNK(751)
  3609. IMPL_THUNK(752)
  3610. IMPL_THUNK(753)
  3611. IMPL_THUNK(754)
  3612. IMPL_THUNK(755)
  3613. IMPL_THUNK(756)
  3614. IMPL_THUNK(757)
  3615. IMPL_THUNK(758)
  3616. IMPL_THUNK(759)
  3617. IMPL_THUNK(760)
  3618. IMPL_THUNK(761)
  3619. IMPL_THUNK(762)
  3620. IMPL_THUNK(763)
  3621. IMPL_THUNK(764)
  3622. IMPL_THUNK(765)
  3623. IMPL_THUNK(766)
  3624. IMPL_THUNK(767)
  3625. IMPL_THUNK(768)
  3626. IMPL_THUNK(769)
  3627. IMPL_THUNK(770)
  3628. IMPL_THUNK(771)
  3629. IMPL_THUNK(772)
  3630. IMPL_THUNK(773)
  3631. IMPL_THUNK(774)
  3632. IMPL_THUNK(775)
  3633. IMPL_THUNK(776)
  3634. IMPL_THUNK(777)
  3635. IMPL_THUNK(778)
  3636. IMPL_THUNK(779)
  3637. IMPL_THUNK(780)
  3638. IMPL_THUNK(781)
  3639. IMPL_THUNK(782)
  3640. IMPL_THUNK(783)
  3641. IMPL_THUNK(784)
  3642. IMPL_THUNK(785)
  3643. IMPL_THUNK(786)
  3644. IMPL_THUNK(787)
  3645. IMPL_THUNK(788)
  3646. IMPL_THUNK(789)
  3647. IMPL_THUNK(790)
  3648. IMPL_THUNK(791)
  3649. IMPL_THUNK(792)
  3650. IMPL_THUNK(793)
  3651. IMPL_THUNK(794)
  3652. IMPL_THUNK(795)
  3653. IMPL_THUNK(796)
  3654. IMPL_THUNK(797)
  3655. IMPL_THUNK(798)
  3656. IMPL_THUNK(799)
  3657. IMPL_THUNK(800)
  3658. IMPL_THUNK(801)
  3659. IMPL_THUNK(802)
  3660. IMPL_THUNK(803)
  3661. IMPL_THUNK(804)
  3662. IMPL_THUNK(805)
  3663. IMPL_THUNK(806)
  3664. IMPL_THUNK(807)
  3665. IMPL_THUNK(808)
  3666. IMPL_THUNK(809)
  3667. IMPL_THUNK(810)
  3668. IMPL_THUNK(811)
  3669. IMPL_THUNK(812)
  3670. IMPL_THUNK(813)
  3671. IMPL_THUNK(814)
  3672. IMPL_THUNK(815)
  3673. IMPL_THUNK(816)
  3674. IMPL_THUNK(817)
  3675. IMPL_THUNK(818)
  3676. IMPL_THUNK(819)
  3677. IMPL_THUNK(820)
  3678. IMPL_THUNK(821)
  3679. IMPL_THUNK(822)
  3680. IMPL_THUNK(823)
  3681. IMPL_THUNK(824)
  3682. IMPL_THUNK(825)
  3683. IMPL_THUNK(826)
  3684. IMPL_THUNK(827)
  3685. IMPL_THUNK(828)
  3686. IMPL_THUNK(829)
  3687. IMPL_THUNK(830)
  3688. IMPL_THUNK(831)
  3689. IMPL_THUNK(832)
  3690. IMPL_THUNK(833)
  3691. IMPL_THUNK(834)
  3692. IMPL_THUNK(835)
  3693. IMPL_THUNK(836)
  3694. IMPL_THUNK(837)
  3695. IMPL_THUNK(838)
  3696. IMPL_THUNK(839)
  3697. IMPL_THUNK(840)
  3698. IMPL_THUNK(841)
  3699. IMPL_THUNK(842)
  3700. IMPL_THUNK(843)
  3701. IMPL_THUNK(844)
  3702. IMPL_THUNK(845)
  3703. IMPL_THUNK(846)
  3704. IMPL_THUNK(847)
  3705. IMPL_THUNK(848)
  3706. IMPL_THUNK(849)
  3707. IMPL_THUNK(850)
  3708. IMPL_THUNK(851)
  3709. IMPL_THUNK(852)
  3710. IMPL_THUNK(853)
  3711. IMPL_THUNK(854)
  3712. IMPL_THUNK(855)
  3713. IMPL_THUNK(856)
  3714. IMPL_THUNK(857)
  3715. IMPL_THUNK(858)
  3716. IMPL_THUNK(859)
  3717. IMPL_THUNK(860)
  3718. IMPL_THUNK(861)
  3719. IMPL_THUNK(862)
  3720. IMPL_THUNK(863)
  3721. IMPL_THUNK(864)
  3722. IMPL_THUNK(865)
  3723. IMPL_THUNK(866)
  3724. IMPL_THUNK(867)
  3725. IMPL_THUNK(868)
  3726. IMPL_THUNK(869)
  3727. IMPL_THUNK(870)
  3728. IMPL_THUNK(871)
  3729. IMPL_THUNK(872)
  3730. IMPL_THUNK(873)
  3731. IMPL_THUNK(874)
  3732. IMPL_THUNK(875)
  3733. IMPL_THUNK(876)
  3734. IMPL_THUNK(877)
  3735. IMPL_THUNK(878)
  3736. IMPL_THUNK(879)
  3737. IMPL_THUNK(880)
  3738. IMPL_THUNK(881)
  3739. IMPL_THUNK(882)
  3740. IMPL_THUNK(883)
  3741. IMPL_THUNK(884)
  3742. IMPL_THUNK(885)
  3743. IMPL_THUNK(886)
  3744. IMPL_THUNK(887)
  3745. IMPL_THUNK(888)
  3746. IMPL_THUNK(889)
  3747. IMPL_THUNK(890)
  3748. IMPL_THUNK(891)
  3749. IMPL_THUNK(892)
  3750. IMPL_THUNK(893)
  3751. IMPL_THUNK(894)
  3752. IMPL_THUNK(895)
  3753. IMPL_THUNK(896)
  3754. IMPL_THUNK(897)
  3755. IMPL_THUNK(898)
  3756. IMPL_THUNK(899)
  3757. IMPL_THUNK(900)
  3758. IMPL_THUNK(901)
  3759. IMPL_THUNK(902)
  3760. IMPL_THUNK(903)
  3761. IMPL_THUNK(904)
  3762. IMPL_THUNK(905)
  3763. IMPL_THUNK(906)
  3764. IMPL_THUNK(907)
  3765. IMPL_THUNK(908)
  3766. IMPL_THUNK(909)
  3767. IMPL_THUNK(910)
  3768. IMPL_THUNK(911)
  3769. IMPL_THUNK(912)
  3770. IMPL_THUNK(913)
  3771. IMPL_THUNK(914)
  3772. IMPL_THUNK(915)
  3773. IMPL_THUNK(916)
  3774. IMPL_THUNK(917)
  3775. IMPL_THUNK(918)
  3776. IMPL_THUNK(919)
  3777. IMPL_THUNK(920)
  3778. IMPL_THUNK(921)
  3779. IMPL_THUNK(922)
  3780. IMPL_THUNK(923)
  3781. IMPL_THUNK(924)
  3782. IMPL_THUNK(925)
  3783. IMPL_THUNK(926)
  3784. IMPL_THUNK(927)
  3785. IMPL_THUNK(928)
  3786. IMPL_THUNK(929)
  3787. IMPL_THUNK(930)
  3788. IMPL_THUNK(931)
  3789. IMPL_THUNK(932)
  3790. IMPL_THUNK(933)
  3791. IMPL_THUNK(934)
  3792. IMPL_THUNK(935)
  3793. IMPL_THUNK(936)
  3794. IMPL_THUNK(937)
  3795. IMPL_THUNK(938)
  3796. IMPL_THUNK(939)
  3797. IMPL_THUNK(940)
  3798. IMPL_THUNK(941)
  3799. IMPL_THUNK(942)
  3800. IMPL_THUNK(943)
  3801. IMPL_THUNK(944)
  3802. IMPL_THUNK(945)
  3803. IMPL_THUNK(946)
  3804. IMPL_THUNK(947)
  3805. IMPL_THUNK(948)
  3806. IMPL_THUNK(949)
  3807. IMPL_THUNK(950)
  3808. IMPL_THUNK(951)
  3809. IMPL_THUNK(952)
  3810. IMPL_THUNK(953)
  3811. IMPL_THUNK(954)
  3812. IMPL_THUNK(955)
  3813. IMPL_THUNK(956)
  3814. IMPL_THUNK(957)
  3815. IMPL_THUNK(958)
  3816. IMPL_THUNK(959)
  3817. IMPL_THUNK(960)
  3818. IMPL_THUNK(961)
  3819. IMPL_THUNK(962)
  3820. IMPL_THUNK(963)
  3821. IMPL_THUNK(964)
  3822. IMPL_THUNK(965)
  3823. IMPL_THUNK(966)
  3824. IMPL_THUNK(967)
  3825. IMPL_THUNK(968)
  3826. IMPL_THUNK(969)
  3827. IMPL_THUNK(970)
  3828. IMPL_THUNK(971)
  3829. IMPL_THUNK(972)
  3830. IMPL_THUNK(973)
  3831. IMPL_THUNK(974)
  3832. IMPL_THUNK(975)
  3833. IMPL_THUNK(976)
  3834. IMPL_THUNK(977)
  3835. IMPL_THUNK(978)
  3836. IMPL_THUNK(979)
  3837. IMPL_THUNK(980)
  3838. IMPL_THUNK(981)
  3839. IMPL_THUNK(982)
  3840. IMPL_THUNK(983)
  3841. IMPL_THUNK(984)
  3842. IMPL_THUNK(985)
  3843. IMPL_THUNK(986)
  3844. IMPL_THUNK(987)
  3845. IMPL_THUNK(988)
  3846. IMPL_THUNK(989)
  3847. IMPL_THUNK(990)
  3848. IMPL_THUNK(991)
  3849. IMPL_THUNK(992)
  3850. IMPL_THUNK(993)
  3851. IMPL_THUNK(994)
  3852. IMPL_THUNK(995)
  3853. IMPL_THUNK(996)
  3854. IMPL_THUNK(997)
  3855. IMPL_THUNK(998)
  3856. IMPL_THUNK(999)
  3857. IMPL_THUNK(1000)
  3858. IMPL_THUNK(1001)
  3859. IMPL_THUNK(1002)
  3860. IMPL_THUNK(1003)
  3861. IMPL_THUNK(1004)
  3862. IMPL_THUNK(1005)
  3863. IMPL_THUNK(1006)
  3864. IMPL_THUNK(1007)
  3865. IMPL_THUNK(1008)
  3866. IMPL_THUNK(1009)
  3867. IMPL_THUNK(1010)
  3868. IMPL_THUNK(1011)
  3869. IMPL_THUNK(1012)
  3870. IMPL_THUNK(1013)
  3871. IMPL_THUNK(1014)
  3872. IMPL_THUNK(1015)
  3873. IMPL_THUNK(1016)
  3874. IMPL_THUNK(1017)
  3875. IMPL_THUNK(1018)
  3876. IMPL_THUNK(1019)
  3877. IMPL_THUNK(1020)
  3878. IMPL_THUNK(1021)
  3879. IMPL_THUNK(1022)
  3880. IMPL_THUNK(1023)
  3881. IMPL_THUNK(1024)
  3882.  
  3883. #endif
  3884.  
  3885. __declspec(selectany) GUID CComModule::m_libid = {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
  3886.  
  3887. #ifdef _ATL_STATIC_REGISTRY
  3888. #define UpdateRegistryFromResource UpdateRegistryFromResourceS
  3889. #else
  3890. #define UpdateRegistryFromResource UpdateRegistryFromResourceD
  3891. #endif
  3892.  
  3893. /////////////////////////////////////////////////////////////////////////////////////////////
  3894. // Thread Pooling classes
  3895.  
  3896. class _AtlAptCreateObjData
  3897. {
  3898. public:
  3899.     _ATL_CREATORFUNC* pfnCreateInstance;
  3900.     const IID* piid;
  3901.     HANDLE hEvent;
  3902.     LPSTREAM pStream;
  3903.     HRESULT hRes;
  3904. };
  3905.  
  3906. class CComApartment
  3907. {
  3908. public:
  3909.     CComApartment()
  3910.     {
  3911.         m_nLockCnt = 0;
  3912.     }
  3913.     static UINT ATL_CREATE_OBJECT;
  3914.     static DWORD WINAPI _Apartment(void* pv)
  3915.     {
  3916.         return ((CComApartment*)pv)->Apartment();
  3917.     }
  3918.     DWORD Apartment()
  3919.     {
  3920. #if !defined(_WIN32_WCE)
  3921.         CoInitialize(NULL);
  3922.         MSG msg;
  3923.         while(GetMessage(&msg, 0, 0, 0))
  3924.         {
  3925.             if (msg.message == ATL_CREATE_OBJECT)
  3926.             {
  3927.                 _AtlAptCreateObjData* pdata = (_AtlAptCreateObjData*)msg.lParam;
  3928.                 IUnknown* pUnk = NULL;
  3929.                 pdata->hRes = pdata->pfnCreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
  3930.                 if (SUCCEEDED(pdata->hRes))
  3931.                     pdata->hRes = CoMarshalInterThreadInterfaceInStream(*pdata->piid, pUnk, &pdata->pStream);
  3932.                 if (SUCCEEDED(pdata->hRes))
  3933.                 {
  3934.                     pUnk->Release();
  3935.                     ATLTRACE2(atlTraceCOM, 2, _T("Object created on thread = %d\n"), GetCurrentThreadId());
  3936.                 }
  3937.                 SetEvent(pdata->hEvent);
  3938.             }
  3939.             DispatchMessage(&msg);
  3940.         }
  3941.         CoUninitialize();
  3942. #endif // _WIN32_WCE
  3943.         return 0;
  3944.     }
  3945.     LONG Lock() {return CComGlobalsThreadModel::Increment(&m_nLockCnt);}
  3946.     LONG Unlock(){return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
  3947.     }
  3948.     LONG GetLockCount() {return m_nLockCnt;}
  3949.  
  3950.     DWORD m_dwThreadID;
  3951.     HANDLE m_hThread;
  3952.     LONG m_nLockCnt;
  3953. };
  3954.  
  3955. __declspec(selectany) UINT CComApartment::ATL_CREATE_OBJECT = 0;
  3956.  
  3957. class CComSimpleThreadAllocator
  3958. {
  3959. public:
  3960.     CComSimpleThreadAllocator()
  3961.     {
  3962.         m_nThread = 0;
  3963.     }
  3964.     int GetThread(CComApartment* /*pApt*/, int nThreads)
  3965.     {
  3966.         if (++m_nThread == nThreads)
  3967.             m_nThread = 0;
  3968.         return m_nThread;
  3969.     }
  3970.     int m_nThread;
  3971. };
  3972.  
  3973. template <class ThreadAllocator = CComSimpleThreadAllocator>
  3974. class CComAutoThreadModule : public CComModule
  3975. {
  3976. public:
  3977.     HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL, int nThreads = GetDefaultThreads());
  3978.     ~CComAutoThreadModule();
  3979.     HRESULT CreateInstance(void* pfnCreateInstance, REFIID riid, void** ppvObj);
  3980.     LONG Lock();
  3981.     LONG Unlock();
  3982.     DWORD dwThreadID;
  3983.     int m_nThreads;
  3984.     CComApartment* m_pApartments;
  3985.     ThreadAllocator m_Allocator;
  3986.     static int GetDefaultThreads()
  3987.     {
  3988.         SYSTEM_INFO si;
  3989.         GetSystemInfo(&si);
  3990.         return si.dwNumberOfProcessors * 4;
  3991.     }
  3992. };
  3993.  
  3994. /////////////////////////////////////////////////////////////////////////////
  3995. // CComBSTR
  3996.  
  3997. class CComBSTR
  3998. {
  3999. public:
  4000.     BSTR m_str;
  4001.     CComBSTR()
  4002.     {
  4003.         m_str = NULL;
  4004.     }
  4005.     /*explicit*/ CComBSTR(int nSize)
  4006.     {
  4007.         m_str = ::SysAllocStringLen(NULL, nSize);
  4008.     }
  4009.     /*explicit*/ CComBSTR(int nSize, LPCOLESTR sz)
  4010.     {
  4011.         m_str = ::SysAllocStringLen(sz, nSize);
  4012.     }
  4013.     /*explicit*/ CComBSTR(LPCOLESTR pSrc)
  4014.     {
  4015.         m_str = ::SysAllocString(pSrc);
  4016.     }
  4017.     /*explicit*/ CComBSTR(const CComBSTR& src)
  4018.     {
  4019.         m_str = src.Copy();
  4020.     }
  4021.     /*explicit*/ CComBSTR(REFGUID src)
  4022.     {
  4023.         LPOLESTR szGuid;
  4024.         StringFromCLSID(src, &szGuid);
  4025.         m_str = ::SysAllocString(szGuid);
  4026.         CoTaskMemFree(szGuid);
  4027.     }
  4028.     CComBSTR& operator=(const CComBSTR& src)
  4029.     {
  4030.         if (m_str != src.m_str)
  4031.         {
  4032.             if (m_str)
  4033.                 ::SysFreeString(m_str);
  4034.             m_str = src.Copy();
  4035.         }
  4036.         return *this;
  4037.     }
  4038.  
  4039.     CComBSTR& operator=(LPCOLESTR pSrc)
  4040.     {
  4041.         ::SysFreeString(m_str);
  4042.         m_str = ::SysAllocString(pSrc);
  4043.         return *this;
  4044.     }
  4045.  
  4046.     ~CComBSTR()
  4047.     {
  4048.         ::SysFreeString(m_str);
  4049.     }
  4050.     unsigned int Length() const
  4051.     {
  4052.         return (m_str == NULL)? 0 : SysStringLen(m_str);
  4053.     }
  4054.     operator BSTR() const
  4055.     {
  4056.         return m_str;
  4057.     }
  4058.     BSTR* operator&()
  4059.     {
  4060.         return &m_str;
  4061.     }
  4062.     BSTR Copy() const
  4063.     {
  4064.         return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  4065.     }
  4066.     HRESULT CopyTo(BSTR* pbstr)
  4067.     {
  4068.         ATLASSERT(pbstr != NULL);
  4069.         if (pbstr == NULL)
  4070.             return E_POINTER;
  4071.         *pbstr = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  4072.         if (*pbstr == NULL)
  4073.             return E_OUTOFMEMORY;
  4074.         return S_OK;
  4075.     }
  4076.     void Attach(BSTR src)
  4077.     {
  4078.         ATLASSERT(m_str == NULL);
  4079.         m_str = src;
  4080.     }
  4081.     BSTR Detach()
  4082.     {
  4083.         BSTR s = m_str;
  4084.         m_str = NULL;
  4085.         return s;
  4086.     }
  4087.     void Empty()
  4088.     {
  4089.         ::SysFreeString(m_str);
  4090.         m_str = NULL;
  4091.     }
  4092.     bool operator!() const
  4093.     {
  4094.         return (m_str == NULL);
  4095.     }
  4096.     HRESULT Append(const CComBSTR& bstrSrc)
  4097.     {
  4098.         return Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));
  4099.     }
  4100.     HRESULT Append(LPCOLESTR lpsz)
  4101.     {
  4102.         return Append(lpsz, ocslen(lpsz));
  4103.     }
  4104.     // a BSTR is just a LPCOLESTR so we need a special version to signify
  4105.     // that we are appending a BSTR
  4106.     HRESULT AppendBSTR(BSTR p)
  4107.     {
  4108.         return Append(p, SysStringLen(p));
  4109.     }
  4110.     HRESULT Append(LPCOLESTR lpsz, int nLen)
  4111.     {
  4112.         int n1 = Length();
  4113.         BSTR b;
  4114.         b = ::SysAllocStringLen(NULL, n1+nLen);
  4115.         if (b == NULL)
  4116.             return E_OUTOFMEMORY;
  4117.         memcpy(b, m_str, n1*sizeof(OLECHAR));
  4118.         memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));
  4119.         b[n1+nLen] = NULL;
  4120.         SysFreeString(m_str);
  4121.         m_str = b;
  4122.         return S_OK;
  4123.     }
  4124.     HRESULT ToLower()
  4125.     {
  4126.         USES_CONVERSION;
  4127.         if (m_str != NULL)
  4128.         {
  4129.             LPTSTR psz = CharLower(OLE2T(m_str));
  4130.             if (psz == NULL)
  4131.                 return E_OUTOFMEMORY;
  4132.             BSTR b = T2BSTR(psz);
  4133.             if (psz == NULL)
  4134.                 return E_OUTOFMEMORY;
  4135.             SysFreeString(m_str);
  4136.             m_str = b;
  4137.         }
  4138.         return S_OK;
  4139.     }
  4140.     HRESULT ToUpper()
  4141.     {
  4142.         USES_CONVERSION;
  4143.         if (m_str != NULL)
  4144.         {
  4145.             LPTSTR psz = CharUpper(OLE2T(m_str));
  4146.             if (psz == NULL)
  4147.                 return E_OUTOFMEMORY;
  4148.             BSTR b = T2BSTR(psz);
  4149.             if (psz == NULL)
  4150.                 return E_OUTOFMEMORY;
  4151.             SysFreeString(m_str);
  4152.             m_str = b;
  4153.         }
  4154.         return S_OK;
  4155.     }
  4156.     bool LoadString(HINSTANCE hInst, UINT nID)
  4157.     {
  4158.         USES_CONVERSION;
  4159.         TCHAR sz[512];
  4160.         UINT nLen = ::LoadString(hInst, nID, sz, 512);
  4161.         ATLASSERT(nLen < 511);
  4162.         SysFreeString(m_str);
  4163.         m_str = (nLen != 0) ? SysAllocString(T2OLE(sz)) : NULL;
  4164.         return (nLen != 0);
  4165.     }
  4166.     bool LoadString(UINT nID)
  4167.     {
  4168.         return LoadString(_pModule->m_hInstResource, nID);
  4169.     }
  4170.  
  4171.     CComBSTR& operator+=(const CComBSTR& bstrSrc)
  4172.     {
  4173.         AppendBSTR(bstrSrc.m_str);
  4174.         return *this;
  4175.     }
  4176.     bool operator<(BSTR bstrSrc) const
  4177.     {
  4178.         if (bstrSrc == NULL && m_str == NULL)
  4179.             return false;
  4180.         if (bstrSrc != NULL && m_str != NULL)
  4181.             return wcscmp(m_str, bstrSrc) < 0;
  4182.         return m_str == NULL;
  4183.     }
  4184.     bool operator==(BSTR bstrSrc) const
  4185.     {
  4186.         if (bstrSrc == NULL && m_str == NULL)
  4187.             return true;
  4188.         if (bstrSrc != NULL && m_str != NULL)
  4189.             return wcscmp(m_str, bstrSrc) == 0;
  4190.         return false; 
  4191.     }
  4192.     bool operator<(LPCSTR pszSrc) const
  4193.     {
  4194.         if (pszSrc == NULL && m_str == NULL)
  4195.             return false;
  4196.         USES_CONVERSION;
  4197.         if (pszSrc != NULL && m_str != NULL)
  4198.             return wcscmp(m_str, A2W(pszSrc)) < 0;
  4199.         return m_str == NULL;
  4200.     }
  4201.     bool operator==(LPCSTR pszSrc) const
  4202.     {
  4203.         if (pszSrc == NULL && m_str == NULL)
  4204.             return true;
  4205.         USES_CONVERSION;
  4206.         if (pszSrc != NULL && m_str != NULL)
  4207.             return wcscmp(m_str, A2W(pszSrc)) == 0;
  4208.         return false; 
  4209.     }
  4210. #ifndef OLE2ANSI
  4211.     CComBSTR(LPCSTR pSrc)
  4212.     {
  4213.         m_str = A2WBSTR(pSrc);
  4214.     }
  4215.  
  4216.     CComBSTR(int nSize, LPCSTR sz)
  4217.     {
  4218.         m_str = A2WBSTR(sz, nSize);
  4219.     }
  4220.  
  4221.     void Append(LPCSTR lpsz)
  4222.     {
  4223.         USES_CONVERSION;
  4224.         LPCOLESTR lpo = A2COLE(lpsz);
  4225.         Append(lpo, ocslen(lpo));
  4226.     }
  4227.  
  4228.     CComBSTR& operator=(LPCSTR pSrc)
  4229.     {
  4230.         ::SysFreeString(m_str);
  4231.         m_str = A2WBSTR(pSrc);
  4232.         return *this;
  4233.     }
  4234. #endif
  4235.     HRESULT WriteToStream(IStream* pStream)
  4236.     {
  4237.         ATLASSERT(pStream != NULL);
  4238.         ULONG cb;
  4239.         ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+sizeof(OLECHAR) : 0;
  4240.         HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
  4241.         if (FAILED(hr))
  4242.             return hr;
  4243.         return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
  4244.     }
  4245.     HRESULT ReadFromStream(IStream* pStream)
  4246.     {
  4247.         ATLASSERT(pStream != NULL);
  4248.         ATLASSERT(m_str == NULL); // should be empty
  4249.         ULONG cbStrLen = 0;
  4250.         HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);
  4251.         if ((hr == S_OK) && (cbStrLen != 0))
  4252.         {
  4253.             //subtract size for terminating NULL which we wrote out
  4254.             //since SysAllocStringByteLen overallocates for the NULL
  4255.             m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
  4256.             if (m_str == NULL)
  4257.                 hr = E_OUTOFMEMORY;
  4258.             else
  4259.                 hr = pStream->Read((void*) m_str, cbStrLen, NULL);
  4260.         }
  4261.         if (hr == S_FALSE)
  4262.             hr = E_FAIL;
  4263.         return hr;
  4264.     }
  4265. };
  4266.  
  4267. /////////////////////////////////////////////////////////////////////////////
  4268. // CComVariant
  4269.  
  4270. class CComVariant : public tagVARIANT
  4271. {
  4272. // Constructors
  4273. public:
  4274.     CComVariant()
  4275.     {
  4276.         vt = VT_EMPTY;
  4277.     }
  4278.     ~CComVariant()
  4279.     {
  4280.         Clear();
  4281.     }
  4282.  
  4283.     CComVariant(const VARIANT& varSrc)
  4284.     {
  4285.         vt = VT_EMPTY;
  4286.         InternalCopy(&varSrc);
  4287.     }
  4288.  
  4289.     CComVariant(const CComVariant& varSrc)
  4290.     {
  4291.         vt = VT_EMPTY;
  4292.         InternalCopy(&varSrc);
  4293.     }
  4294.  
  4295.     CComVariant(BSTR bstrSrc)
  4296.     {
  4297.         vt = VT_EMPTY;
  4298.         *this = bstrSrc;
  4299.     }
  4300.     CComVariant(LPCOLESTR lpszSrc)
  4301.     {
  4302.         vt = VT_EMPTY;
  4303.         *this = lpszSrc;
  4304.     }
  4305.  
  4306. #ifndef OLE2ANSI
  4307.     CComVariant(LPCSTR lpszSrc)
  4308.     {
  4309.         vt = VT_EMPTY;
  4310.         *this = lpszSrc;
  4311.     }
  4312. #endif
  4313.  
  4314.     CComVariant(bool bSrc)
  4315.     {
  4316.         vt = VT_BOOL;
  4317. #pragma warning(disable: 4310) // cast truncates constant value
  4318.         boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  4319. #pragma warning(default: 4310) // cast truncates constant value
  4320.     }
  4321.  
  4322.     CComVariant(int nSrc)
  4323.     {
  4324.         vt = VT_I4;
  4325.         lVal = nSrc;
  4326.     }
  4327.     CComVariant(BYTE nSrc)
  4328.     {
  4329.         vt = VT_UI1;
  4330.         bVal = nSrc;
  4331.     }
  4332.     CComVariant(short nSrc)
  4333.     {
  4334.         vt = VT_I2;
  4335.         iVal = nSrc;
  4336.     }
  4337.     CComVariant(long nSrc, VARTYPE vtSrc = VT_I4)
  4338.     {
  4339.         ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR);
  4340.         vt = vtSrc;
  4341.         lVal = nSrc;
  4342.     }
  4343.     CComVariant(float fltSrc)
  4344.     {
  4345.         vt = VT_R4;
  4346.         fltVal = fltSrc;
  4347.     }
  4348.     CComVariant(double dblSrc)
  4349.     {
  4350.         vt = VT_R8;
  4351.         dblVal = dblSrc;
  4352.     }
  4353.     CComVariant(CY cySrc)
  4354.     {
  4355.         vt = VT_CY;
  4356.         cyVal.Hi = cySrc.Hi;
  4357.         cyVal.Lo = cySrc.Lo;
  4358.     }
  4359.     CComVariant(IDispatch* pSrc)
  4360.     {
  4361.         vt = VT_DISPATCH;
  4362.         pdispVal = pSrc;
  4363.         // Need to AddRef as VariantClear will Release
  4364.         if (pdispVal != NULL)
  4365.             pdispVal->AddRef();
  4366.     }
  4367.     CComVariant(IUnknown* pSrc)
  4368.     {
  4369.         vt = VT_UNKNOWN;
  4370.         punkVal = pSrc;
  4371.         // Need to AddRef as VariantClear will Release
  4372.         if (punkVal != NULL)
  4373.             punkVal->AddRef();
  4374.     }
  4375.  
  4376. // Assignment Operators
  4377. public:
  4378.     CComVariant& operator=(const CComVariant& varSrc)
  4379.     {
  4380.         InternalCopy(&varSrc);
  4381.         return *this;
  4382.     }
  4383.     CComVariant& operator=(const VARIANT& varSrc)
  4384.     {
  4385.         InternalCopy(&varSrc);
  4386.         return *this;
  4387.     }
  4388.  
  4389.     CComVariant& operator=(BSTR bstrSrc)
  4390.     {
  4391.         InternalClear();
  4392.         vt = VT_BSTR;
  4393.         bstrVal = ::SysAllocString(bstrSrc);
  4394.         if (bstrVal == NULL && bstrSrc != NULL)
  4395.         {
  4396.             vt = VT_ERROR;
  4397.             scode = E_OUTOFMEMORY;
  4398.         }
  4399.         return *this;
  4400.     }
  4401.  
  4402.     CComVariant& operator=(LPCOLESTR lpszSrc)
  4403.     {
  4404.         InternalClear();
  4405.         vt = VT_BSTR;
  4406.         bstrVal = ::SysAllocString(lpszSrc);
  4407.  
  4408.         if (bstrVal == NULL && lpszSrc != NULL)
  4409.         {
  4410.             vt = VT_ERROR;
  4411.             scode = E_OUTOFMEMORY;
  4412.         }
  4413.         return *this;
  4414.     }
  4415.  
  4416.     #ifndef OLE2ANSI
  4417.     CComVariant& operator=(LPCSTR lpszSrc)
  4418.     {
  4419.         USES_CONVERSION;
  4420.         InternalClear();
  4421.         vt = VT_BSTR;
  4422.         bstrVal = ::SysAllocString(A2COLE(lpszSrc));
  4423.  
  4424.         if (bstrVal == NULL && lpszSrc != NULL)
  4425.         {
  4426.             vt = VT_ERROR;
  4427.             scode = E_OUTOFMEMORY;
  4428.         }
  4429.         return *this;
  4430.     }
  4431.     #endif
  4432.  
  4433.     CComVariant& operator=(bool bSrc)
  4434.     {
  4435.         if (vt != VT_BOOL)
  4436.         {
  4437.             InternalClear();
  4438.             vt = VT_BOOL;
  4439.         }
  4440.     #pragma warning(disable: 4310) // cast truncates constant value
  4441.         boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  4442.     #pragma warning(default: 4310) // cast truncates constant value
  4443.         return *this;
  4444.     }
  4445.  
  4446.     CComVariant& operator=(int nSrc)
  4447.     {
  4448.         if (vt != VT_I4)
  4449.         {
  4450.             InternalClear();
  4451.             vt = VT_I4;
  4452.         }
  4453.         lVal = nSrc;
  4454.  
  4455.         return *this;
  4456.     }
  4457.  
  4458.     CComVariant& operator=(BYTE nSrc)
  4459.     {
  4460.         if (vt != VT_UI1)
  4461.         {
  4462.             InternalClear();
  4463.             vt = VT_UI1;
  4464.         }
  4465.         bVal = nSrc;
  4466.         return *this;
  4467.     }
  4468.  
  4469.     CComVariant& operator=(short nSrc)
  4470.     {
  4471.         if (vt != VT_I2)
  4472.         {
  4473.             InternalClear();
  4474.             vt = VT_I2;
  4475.         }
  4476.         iVal = nSrc;
  4477.         return *this;
  4478.     }
  4479.  
  4480.     CComVariant& operator=(long nSrc)
  4481.     {
  4482.         if (vt != VT_I4)
  4483.         {
  4484.             InternalClear();
  4485.             vt = VT_I4;
  4486.         }
  4487.         lVal = nSrc;
  4488.         return *this;
  4489.     }
  4490.  
  4491.     CComVariant& operator=(float fltSrc)
  4492.     {
  4493.         if (vt != VT_R4)
  4494.         {
  4495.             InternalClear();
  4496.             vt = VT_R4;
  4497.         }
  4498.         fltVal = fltSrc;
  4499.         return *this;
  4500.     }
  4501.  
  4502.     CComVariant& operator=(double dblSrc)
  4503.     {
  4504.         if (vt != VT_R8)
  4505.         {
  4506.             InternalClear();
  4507.             vt = VT_R8;
  4508.         }
  4509.         dblVal = dblSrc;
  4510.         return *this;
  4511.     }
  4512.  
  4513.     CComVariant& operator=(CY cySrc)
  4514.     {
  4515.         if (vt != VT_CY)
  4516.         {
  4517.             InternalClear();
  4518.             vt = VT_CY;
  4519.         }
  4520.         cyVal.Hi = cySrc.Hi;
  4521.         cyVal.Lo = cySrc.Lo;
  4522.         return *this;
  4523.     }
  4524.  
  4525.     CComVariant& operator=(IDispatch* pSrc)
  4526.     {
  4527.         InternalClear();
  4528.         vt = VT_DISPATCH;
  4529.         pdispVal = pSrc;
  4530.         // Need to AddRef as VariantClear will Release
  4531.         if (pdispVal != NULL)
  4532.             pdispVal->AddRef();
  4533.         return *this;
  4534.     }
  4535.  
  4536.     CComVariant& operator=(IUnknown* pSrc)
  4537.     {
  4538.         InternalClear();
  4539.         vt = VT_UNKNOWN;
  4540.         punkVal = pSrc;
  4541.  
  4542.         // Need to AddRef as VariantClear will Release
  4543.         if (punkVal != NULL)
  4544.             punkVal->AddRef();
  4545.         return *this;
  4546.     }
  4547.  
  4548.  
  4549. // Comparison Operators
  4550. public:
  4551.     bool operator==(const VARIANT& varSrc) const
  4552.     {
  4553.         if (this == &varSrc)
  4554.             return true;
  4555.  
  4556.         // Variants not equal if types don't match
  4557.         if (vt != varSrc.vt)
  4558.             return false;
  4559.  
  4560.         // Check type specific values
  4561.         switch (vt)
  4562.         {
  4563.             case VT_EMPTY:
  4564.             case VT_NULL:
  4565.                 return true;
  4566.  
  4567.             case VT_BOOL:
  4568.                 return boolVal == varSrc.boolVal;
  4569.  
  4570.             case VT_UI1:
  4571.                 return bVal == varSrc.bVal;
  4572.  
  4573.             case VT_I2:
  4574.                 return iVal == varSrc.iVal;
  4575.  
  4576.             case VT_I4:
  4577.                 return lVal == varSrc.lVal;
  4578.  
  4579.             case VT_R4:
  4580.                 return fltVal == varSrc.fltVal;
  4581.  
  4582.             case VT_R8:
  4583.                 return dblVal == varSrc.dblVal;
  4584.  
  4585.             case VT_BSTR:
  4586.                 return (::SysStringByteLen(bstrVal) == ::SysStringByteLen(varSrc.bstrVal)) &&
  4587.                         (::memcmp(bstrVal, varSrc.bstrVal, ::SysStringByteLen(bstrVal)) == 0);
  4588.  
  4589.             case VT_ERROR:
  4590.                 return scode == varSrc.scode;
  4591.  
  4592.             case VT_DISPATCH:
  4593.                 return pdispVal == varSrc.pdispVal;
  4594.  
  4595.             case VT_UNKNOWN:
  4596.                 return punkVal == varSrc.punkVal;
  4597.  
  4598.             default:
  4599.                 ATLASSERT(false);
  4600.                 // fall through
  4601.         }
  4602.  
  4603.         return false;
  4604.     }
  4605.     bool operator!=(const VARIANT& varSrc) const {return !operator==(varSrc);}
  4606. WCE_DEL bool operator<(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT)==VARCMP_LT;}
  4607. WCE_DEL bool operator>(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT)==VARCMP_GT;}
  4608.  
  4609. // Operations
  4610. public:
  4611.     HRESULT Clear() { return ::VariantClear(this); }
  4612.     HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); }
  4613.     HRESULT Attach(VARIANT* pSrc)
  4614.     {
  4615.         // Clear out the variant
  4616.         HRESULT hr = Clear();
  4617.         if (!FAILED(hr))
  4618.         {
  4619.             // Copy the contents and give control to CComVariant
  4620.             memcpy(this, pSrc, sizeof(VARIANT));
  4621.             pSrc->vt = VT_EMPTY;
  4622.             hr = S_OK;
  4623.         }
  4624.         return hr;
  4625.     }
  4626.  
  4627.     HRESULT Detach(VARIANT* pDest)
  4628.     {
  4629.         // Clear out the variant
  4630.         HRESULT hr = ::VariantClear(pDest);
  4631.         if (!FAILED(hr))
  4632.         {
  4633.             // Copy the contents and remove control from CComVariant
  4634.             memcpy(pDest, this, sizeof(VARIANT));
  4635.             vt = VT_EMPTY;
  4636.             hr = S_OK;
  4637.         }
  4638.         return hr;
  4639.     }
  4640.  
  4641.     HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL)
  4642.     {
  4643.         VARIANT* pVar = const_cast<VARIANT*>(pSrc);
  4644.         // Convert in place if pSrc is NULL
  4645.         if (pVar == NULL)
  4646.             pVar = this;
  4647.         // Do nothing if doing in place convert and vts not different
  4648.         return ::VariantChangeType(this, pVar, 0, vtNew);
  4649.     }
  4650.  
  4651.     HRESULT WriteToStream(IStream* pStream);
  4652.     HRESULT ReadFromStream(IStream* pStream);
  4653.  
  4654. // Implementation
  4655. public:
  4656.     HRESULT InternalClear()
  4657.     {
  4658.         HRESULT hr = Clear();
  4659.         ATLASSERT(SUCCEEDED(hr));
  4660.         if (FAILED(hr))
  4661.         {
  4662.             vt = VT_ERROR;
  4663.             scode = hr;
  4664.         }
  4665.         return hr;
  4666.     }
  4667.  
  4668.     void InternalCopy(const VARIANT* pSrc)
  4669.     {
  4670.         HRESULT hr = Copy(pSrc);
  4671.         if (FAILED(hr))
  4672.         {
  4673.             vt = VT_ERROR;
  4674.             scode = hr;
  4675.         }
  4676.     }
  4677. };
  4678.  
  4679. inline HRESULT CComVariant::WriteToStream(IStream* pStream)
  4680. {
  4681.     HRESULT hr = pStream->Write(&vt, sizeof(VARTYPE), NULL);
  4682.     if (FAILED(hr))
  4683.         return hr;
  4684.  
  4685.     int cbWrite = 0;
  4686.     switch (vt)
  4687.     {
  4688.     case VT_UNKNOWN:
  4689.     case VT_DISPATCH:
  4690.         {
  4691.             CComPtr<IPersistStream> spStream;
  4692.             if (punkVal != NULL)
  4693.             {
  4694.                 hr = punkVal->QueryInterface(IID_IPersistStream, (void**)&spStream);
  4695.                 if (FAILED(hr))
  4696.                     return hr;
  4697.             }
  4698.             if (spStream != NULL)
  4699.                 return WCE_FCTN(OleSaveToStream)(spStream, pStream);
  4700.             else
  4701.                 return WriteClassStm(pStream, CLSID_NULL);
  4702.         }
  4703.     case VT_UI1:
  4704.     case VT_I1:
  4705.         cbWrite = sizeof(BYTE);
  4706.         break;
  4707.     case VT_I2:
  4708.     case VT_UI2:
  4709.     case VT_BOOL:
  4710.         cbWrite = sizeof(short);
  4711.         break;
  4712.     case VT_I4:
  4713.     case VT_UI4:
  4714.     case VT_R4:
  4715.     case VT_INT:
  4716.     case VT_UINT:
  4717.     case VT_ERROR:
  4718.         cbWrite = sizeof(long);
  4719.         break;
  4720.     case VT_R8:
  4721.     case VT_CY:
  4722.     case VT_DATE:
  4723.         cbWrite = sizeof(double);
  4724.         break;
  4725.     default:
  4726.         break;
  4727.     }
  4728.     if (cbWrite != 0)
  4729.         return pStream->Write((void*) &bVal, cbWrite, NULL);
  4730.  
  4731.     CComBSTR bstrWrite;
  4732.     CComVariant varBSTR;
  4733.     if (vt != VT_BSTR)
  4734.     {
  4735.         hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR);
  4736.         if (FAILED(hr))
  4737.             return hr;
  4738.         bstrWrite = varBSTR.bstrVal;
  4739.     }
  4740.     else
  4741.         bstrWrite = bstrVal;
  4742.  
  4743.     return bstrWrite.WriteToStream(pStream);
  4744. }
  4745.  
  4746. inline HRESULT CComVariant::ReadFromStream(IStream* pStream)
  4747. {
  4748.     ATLASSERT(pStream != NULL);
  4749.     HRESULT hr;
  4750.     hr = VariantClear(this);
  4751.     if (FAILED(hr))
  4752.         return hr;
  4753.     VARTYPE vtRead;
  4754.     hr = pStream->Read(&vtRead, sizeof(VARTYPE), NULL);
  4755.     if (hr == S_FALSE)
  4756.         hr = E_FAIL;
  4757.     if (FAILED(hr))
  4758.         return hr;
  4759.  
  4760.     vt = vtRead;
  4761.     int cbRead = 0;
  4762.     switch (vtRead)
  4763.     {
  4764.     case VT_UNKNOWN:
  4765.     case VT_DISPATCH:
  4766.         {
  4767.             punkVal = NULL;
  4768.             hr = WCE_FCTN(OleLoadFromStream)(pStream, (vtRead == VT_UNKNOWN) ? IID_IUnknown : IID_IDispatch, (void**)&punkVal);
  4769.             if (hr == REGDB_E_CLASSNOTREG)
  4770.                 hr = S_OK;
  4771.             return S_OK;
  4772.         }
  4773.     case VT_UI1:
  4774.     case VT_I1:
  4775.         cbRead = sizeof(BYTE);
  4776.         break;
  4777.     case VT_I2:
  4778.     case VT_UI2:
  4779.     case VT_BOOL:
  4780.         cbRead = sizeof(short);
  4781.         break;
  4782.     case VT_I4:
  4783.     case VT_UI4:
  4784.     case VT_R4:
  4785.     case VT_INT:
  4786.     case VT_UINT:
  4787.     case VT_ERROR:
  4788.         cbRead = sizeof(long);
  4789.         break;
  4790.     case VT_R8:
  4791.     case VT_CY:
  4792.     case VT_DATE:
  4793.         cbRead = sizeof(double);
  4794.         break;
  4795.     default:
  4796.         break;
  4797.     }
  4798.     if (cbRead != 0)
  4799.     {
  4800.         hr = pStream->Read((void*) &bVal, cbRead, NULL);
  4801.         if (hr == S_FALSE)
  4802.             hr = E_FAIL;
  4803.         return hr;
  4804.     }
  4805.     CComBSTR bstrRead;
  4806.  
  4807.     hr = bstrRead.ReadFromStream(pStream);
  4808.     if (FAILED(hr))
  4809.         return hr;
  4810.     vt = VT_BSTR;
  4811.     bstrVal = bstrRead.Detach();
  4812.     if (vtRead != VT_BSTR)
  4813.         hr = ChangeType(vtRead);
  4814.     return hr;
  4815. }
  4816.  
  4817. /////////////////////////////////////////////////////////////////////////////
  4818. // CRegKey
  4819.  
  4820. class CRegKey
  4821. {
  4822. public:
  4823.     CRegKey();
  4824.     ~CRegKey();
  4825.  
  4826. // Attributes
  4827. public:
  4828.     operator HKEY() const;
  4829.     HKEY m_hKey;
  4830.  
  4831. // Operations
  4832. public:
  4833.     LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
  4834.     LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
  4835.     LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);
  4836.     LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  4837.  
  4838.     LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  4839.     static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4840.         LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
  4841.  
  4842.     LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4843.         LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,
  4844.         REGSAM samDesired = KEY_ALL_ACCESS,
  4845.         LPSECURITY_ATTRIBUTES lpSecAttr = NULL,
  4846.         LPDWORD lpdwDisposition = NULL);
  4847.     LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4848.         REGSAM samDesired = KEY_ALL_ACCESS);
  4849.     LONG Close();
  4850.     HKEY Detach();
  4851.     void Attach(HKEY hKey);
  4852.     LONG DeleteSubKey(LPCTSTR lpszSubKey);
  4853.     LONG RecurseDeleteKey(LPCTSTR lpszKey);
  4854.     LONG DeleteValue(LPCTSTR lpszValue);
  4855. };
  4856.  
  4857. inline CRegKey::CRegKey()
  4858. {m_hKey = NULL;}
  4859.  
  4860. inline CRegKey::~CRegKey()
  4861. {Close();}
  4862.  
  4863. inline CRegKey::operator HKEY() const
  4864. {return m_hKey;}
  4865.  
  4866. inline HKEY CRegKey::Detach()
  4867. {
  4868.     HKEY hKey = m_hKey;
  4869.     m_hKey = NULL;
  4870.     return hKey;
  4871. }
  4872.  
  4873. inline void CRegKey::Attach(HKEY hKey)
  4874. {
  4875.     ATLASSERT(m_hKey == NULL);
  4876.     m_hKey = hKey;
  4877. }
  4878.  
  4879. inline LONG CRegKey::DeleteSubKey(LPCTSTR lpszSubKey)
  4880. {
  4881.     ATLASSERT(m_hKey != NULL);
  4882.     return RegDeleteKey(m_hKey, lpszSubKey);
  4883. }
  4884.  
  4885. inline LONG CRegKey::DeleteValue(LPCTSTR lpszValue)
  4886. {
  4887.     ATLASSERT(m_hKey != NULL);
  4888.     return RegDeleteValue(m_hKey, (LPTSTR)lpszValue);
  4889. }
  4890.  
  4891. inline LONG CRegKey::Close()
  4892. {
  4893.     LONG lRes = ERROR_SUCCESS;
  4894.     if (m_hKey != NULL)
  4895.     {
  4896.         lRes = RegCloseKey(m_hKey);
  4897.         m_hKey = NULL;
  4898.     }
  4899.     return lRes;
  4900. }
  4901.  
  4902. inline LONG CRegKey::Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  4903.     LPTSTR lpszClass, DWORD dwOptions, REGSAM samDesired,
  4904.     LPSECURITY_ATTRIBUTES lpSecAttr, LPDWORD lpdwDisposition)
  4905. {
  4906.     ATLASSERT(hKeyParent != NULL);
  4907.     DWORD dw;
  4908.     HKEY hKey = NULL;
  4909.     LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, 0,
  4910.         lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, &dw);
  4911.     if (lpdwDisposition != NULL)
  4912.         *lpdwDisposition = dw;
  4913.     if (lRes == ERROR_SUCCESS)
  4914.     {
  4915.         lRes = Close();
  4916.         m_hKey = hKey;
  4917.     }
  4918.     return lRes;
  4919. }
  4920.  
  4921. inline LONG CRegKey::Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired)
  4922. {
  4923.     ATLASSERT(hKeyParent != NULL);
  4924.     HKEY hKey = NULL;
  4925.     LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);
  4926.     if (lRes == ERROR_SUCCESS)
  4927.     {
  4928.         lRes = Close();
  4929.         ATLASSERT(lRes == ERROR_SUCCESS);
  4930.         m_hKey = hKey;
  4931.     }
  4932.     return lRes;
  4933. }
  4934.  
  4935. inline LONG CRegKey::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName)
  4936. {
  4937.     DWORD dwType = NULL;
  4938.     DWORD dwCount = sizeof(DWORD);
  4939.     LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
  4940.         (LPBYTE)&dwValue, &dwCount);
  4941.     ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_DWORD));
  4942.     ATLASSERT((lRes!=ERROR_SUCCESS) || (dwCount == sizeof(DWORD)));
  4943.     return lRes;
  4944. }
  4945.  
  4946. inline LONG CRegKey::QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount)
  4947. {
  4948.     ATLASSERT(pdwCount != NULL);
  4949.     DWORD dwType = NULL;
  4950.     LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
  4951.         (LPBYTE)szValue, pdwCount);
  4952.     ATLASSERT((lRes!=ERROR_SUCCESS) || (dwType == REG_SZ) ||
  4953.              (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ));
  4954.     return lRes;
  4955. }
  4956.  
  4957. inline LONG WINAPI CRegKey::SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  4958. {
  4959.     ATLASSERT(lpszValue != NULL);
  4960.     CRegKey key;
  4961.     LONG lRes = key.Create(hKeyParent, lpszKeyName);
  4962.     if (lRes == ERROR_SUCCESS)
  4963.         lRes = key.SetValue(lpszValue, lpszValueName);
  4964.     return lRes;
  4965. }
  4966.  
  4967. inline LONG CRegKey::SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  4968. {
  4969.     ATLASSERT(lpszValue != NULL);
  4970.     CRegKey key;
  4971.     LONG lRes = key.Create(m_hKey, lpszKeyName);
  4972.     if (lRes == ERROR_SUCCESS)
  4973.         lRes = key.SetValue(lpszValue, lpszValueName);
  4974.     return lRes;
  4975. }
  4976.  
  4977. inline LONG CRegKey::SetValue(DWORD dwValue, LPCTSTR lpszValueName)
  4978. {
  4979.     ATLASSERT(m_hKey != NULL);
  4980.     return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_DWORD,
  4981.         (BYTE * const)&dwValue, sizeof(DWORD));
  4982. }
  4983.  
  4984. inline LONG CRegKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName)
  4985. {
  4986.     ATLASSERT(lpszValue != NULL);
  4987.     ATLASSERT(m_hKey != NULL);
  4988.     return RegSetValueEx(m_hKey, lpszValueName, NULL, REG_SZ,
  4989.         (BYTE * const)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR));
  4990. }
  4991.  
  4992. inline LONG CRegKey::RecurseDeleteKey(LPCTSTR lpszKey)
  4993. {
  4994.     CRegKey key;
  4995.     LONG lRes = key.Open(m_hKey, lpszKey, KEY_READ | KEY_WRITE);
  4996.     if (lRes != ERROR_SUCCESS)
  4997.         return lRes;
  4998.     FILETIME time;
  4999.     DWORD dwSize = 256;
  5000.     TCHAR szBuffer[256];
  5001.     while (RegEnumKeyEx(key.m_hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL,
  5002.         &time)==ERROR_SUCCESS)
  5003.     {
  5004.         lRes = key.RecurseDeleteKey(szBuffer);
  5005.         if (lRes != ERROR_SUCCESS)
  5006.             return lRes;
  5007.         dwSize = 256;
  5008.     }
  5009.     key.Close();
  5010.     return DeleteSubKey(lpszKey);
  5011. }
  5012.  
  5013. inline HRESULT CComModule::RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc)
  5014. {
  5015.     CRegKey keyProgID;
  5016.     LONG lRes = keyProgID.Create(HKEY_CLASSES_ROOT, lpszProgID, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ);
  5017.     if (lRes == ERROR_SUCCESS)
  5018.     {
  5019.         keyProgID.SetValue(lpszUserDesc);
  5020.         keyProgID.SetKeyValue(_T("CLSID"), lpszCLSID);
  5021.         return S_OK;
  5022.     }
  5023.     return HRESULT_FROM_WIN32(lRes);
  5024. }
  5025.  
  5026. #ifdef _ATL_STATIC_REGISTRY
  5027. #include <statreg.h>
  5028.  
  5029. // Statically linking to Registry Ponent
  5030. inline HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  5031.     struct _ATL_REGMAP_ENTRY* pMapEntries)
  5032. {
  5033.     USES_CONVERSION;
  5034.     ATL::CRegObject ro;
  5035.     TCHAR szModule[_MAX_PATH];
  5036.     GetModuleFileName(_pModule->GetModuleInstance(), szModule, _MAX_PATH);
  5037.  
  5038.    // Convert to short path to work around bug in NT4's CreateProcess
  5039.     WCE_DEL TCHAR szModuleShort[_MAX_PATH];
  5040.     WCE_DEL GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5041.     LPOLESTR pszModule = T2OLE(WCE_IF(szModule, szModuleShort));
  5042.  
  5043.     int nLen = ocslen(pszModule);
  5044.     LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  5045.     ReplaceSingleQuote(pszModuleQuote, pszModule);
  5046.     ro.AddReplacement(OLESTR("Module"), pszModuleQuote);
  5047.     if (NULL != pMapEntries)
  5048.     {
  5049.         while (NULL != pMapEntries->szKey)
  5050.         {
  5051.             ATLASSERT(NULL != pMapEntries->szData);
  5052.             ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  5053.             pMapEntries++;
  5054.         }
  5055.     }
  5056.  
  5057.     LPCOLESTR szType = OLESTR("REGISTRY");
  5058.     return (bRegister) ? ro.ResourceRegister(pszModule, nResID, szType) :
  5059.             ro.ResourceUnregister(pszModule, nResID, szType);
  5060. }
  5061.  
  5062. inline HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  5063.     struct _ATL_REGMAP_ENTRY* pMapEntries)
  5064. {
  5065.     USES_CONVERSION;
  5066.     ATL::CRegObject ro;
  5067.     TCHAR szModule[_MAX_PATH];
  5068.     GetModuleFileName(_pModule->GetModuleInstance(), szModule, _MAX_PATH);
  5069.  
  5070.    // Convert to short path to work around bug in NT4's CreateProcess
  5071.     WCE_DEL TCHAR szModuleShort[_MAX_PATH];
  5072.     WCE_DEL GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5073.     LPOLESTR pszModule = T2OLE(WCE_IF(szModule,szModuleShort));
  5074.  
  5075.     int nLen = ocslen(pszModule);
  5076.     LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  5077.     ReplaceSingleQuote(pszModuleQuote, pszModule);
  5078.     ro.AddReplacement(OLESTR("Module"), pszModuleQuote);
  5079.     if (NULL != pMapEntries)
  5080.     {
  5081.         while (NULL != pMapEntries->szKey)
  5082.         {
  5083.             ATLASSERT(NULL != pMapEntries->szData);
  5084.             ro.AddReplacement(pMapEntries->szKey, pMapEntries->szData);
  5085.             pMapEntries++;
  5086.         }
  5087.     }
  5088.  
  5089.     LPCOLESTR szType = OLESTR("REGISTRY");
  5090.     LPCOLESTR pszRes = T2COLE(lpszRes);
  5091.     return (bRegister) ? ro.ResourceRegisterSz(pszModule, pszRes, szType) :
  5092.             ro.ResourceUnregisterSz(pszModule, pszRes, szType);
  5093. }
  5094. #endif //_ATL_STATIC_REGISTRY
  5095.  
  5096. inline HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  5097.     LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister)
  5098. {
  5099.     if (bRegister)
  5100.     {
  5101.         return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, nDescID,
  5102.             dwFlags);
  5103.     }
  5104.     else
  5105.         return UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);
  5106. }
  5107.  
  5108. inline HRESULT WINAPI CComModule::RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  5109.     LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags)
  5110. {
  5111.     static const TCHAR szProgID[] = _T("ProgID");
  5112.     static const TCHAR szVIProgID[] = _T("VersionIndependentProgID");
  5113.     static const TCHAR szLS32[] = _T("LocalServer32");
  5114.     static const TCHAR szIPS32[] = _T("InprocServer32");
  5115.     static const TCHAR szThreadingModel[] = _T("ThreadingModel");
  5116.     static const TCHAR szAUTPRX32[] = _T("AUTPRX32.DLL");
  5117.     static const TCHAR szApartment[] = _T("Apartment");
  5118.     static const TCHAR szBoth[] = _T("both");
  5119.     USES_CONVERSION;
  5120.     HRESULT hRes = S_OK;
  5121.     TCHAR szDesc[256];
  5122.     LoadString(m_hInst, nDescID, szDesc, 256);
  5123.     TCHAR szModule[_MAX_PATH];
  5124.     GetModuleFileName(m_hInst, szModule, _MAX_PATH);
  5125.  
  5126.     LPOLESTR lpOleStr;
  5127.     StringFromCLSID(clsid, &lpOleStr);
  5128.     LPTSTR lpsz = OLE2T(lpOleStr);
  5129.  
  5130.     hRes = RegisterProgID(lpsz, lpszProgID, szDesc);
  5131.     if (hRes == S_OK)
  5132.         hRes = RegisterProgID(lpsz, lpszVerIndProgID, szDesc);
  5133.     LONG lRes = ERROR_SUCCESS;
  5134.     if (hRes == S_OK)
  5135.     {
  5136.         CRegKey key;
  5137.         lRes = key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ);
  5138.         if (lRes == ERROR_SUCCESS)
  5139.         {
  5140.             lRes = key.Create(key, lpsz, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_READ);
  5141.             if (lRes == ERROR_SUCCESS)
  5142.             {
  5143.                 key.SetValue(szDesc);
  5144.                 key.SetKeyValue(szProgID, lpszProgID);
  5145.                 key.SetKeyValue(szVIProgID, lpszVerIndProgID);
  5146.  
  5147. #if !defined(_WIN32_WCE)
  5148. // WinCE: No out-of-proc servers.
  5149.                 if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE
  5150.                 {
  5151.                     // Convert to short path to work around bug in NT4's CreateProcess
  5152.                     TCHAR szModuleShort[_MAX_PATH];
  5153.                     GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  5154.                     key.SetKeyValue(szLS32, szModuleShort);
  5155.                 }
  5156.                 else
  5157. #endif // _WIN32_WCE
  5158.                 {
  5159.                     key.SetKeyValue(szIPS32, (dwFlags & AUTPRXFLAG) ? szAUTPRX32 : szModule);
  5160.                     LPCTSTR lpszModel = (dwFlags & THREADFLAGS_BOTH) ? szBoth :
  5161.                         (dwFlags & THREADFLAGS_APARTMENT) ? szApartment : NULL;
  5162.                     if (lpszModel != NULL)
  5163.                         key.SetKeyValue(szIPS32, lpszModel, szThreadingModel);
  5164.                 }
  5165.             }
  5166.         }
  5167.     }
  5168.     CoTaskMemFree(lpOleStr);
  5169.     if (lRes != ERROR_SUCCESS)
  5170.         hRes = HRESULT_FROM_WIN32(lRes);
  5171.     return hRes;
  5172. }
  5173.  
  5174. inline HRESULT WINAPI CComModule::UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  5175.     LPCTSTR lpszVerIndProgID)
  5176. {
  5177.     USES_CONVERSION;
  5178.     CRegKey key;
  5179.  
  5180.     key.Attach(HKEY_CLASSES_ROOT);
  5181.     if (lpszProgID != NULL && lstrcmpi(lpszProgID, _T("")))
  5182.         key.RecurseDeleteKey(lpszProgID);
  5183.     if (lpszVerIndProgID != NULL && lstrcmpi(lpszVerIndProgID, _T("")))
  5184.         key.RecurseDeleteKey(lpszVerIndProgID);
  5185.     LPOLESTR lpOleStr;
  5186.     StringFromCLSID(clsid, &lpOleStr);
  5187.     LPTSTR lpsz = OLE2T(lpOleStr);
  5188.     if (key.Open(key, _T("CLSID"), KEY_READ) == ERROR_SUCCESS)
  5189.         key.RecurseDeleteKey(lpsz);
  5190.     CoTaskMemFree(lpOleStr);
  5191.     return S_OK;
  5192. }
  5193.  
  5194. /////////////////////////////////////////////////////////////////////////////
  5195. // Large Block Allocation Helper - CVBufHelper & CVirtualBuffer
  5196.  
  5197.  
  5198. template <class T>
  5199. class CVBufHelper
  5200. {
  5201. public:
  5202.     virtual T* operator()(T* pCurrent) {return pCurrent;}
  5203. };
  5204.  
  5205. template <class T>
  5206. class CVirtualBuffer
  5207. {
  5208. protected:
  5209.     CVirtualBuffer() {}
  5210.     T* m_pBase;
  5211.     T* m_pCurrent;
  5212.     T* m_pTop;
  5213.     int m_nMaxElements;
  5214. public:
  5215.     CVirtualBuffer(int nMaxElements)
  5216.     {
  5217.         m_nMaxElements = nMaxElements;
  5218.         m_pBase = (T*) VirtualAlloc(NULL, sizeof(T) * nMaxElements,
  5219.             MEM_RESERVE, PAGE_READWRITE);
  5220.         m_pTop = m_pCurrent = m_pBase;
  5221.         // Commit first page - chances are this is all that will be used
  5222.         VirtualAlloc(m_pBase, sizeof(T), MEM_COMMIT, PAGE_READWRITE);
  5223.     }
  5224.     ~CVirtualBuffer()
  5225.     {
  5226.         VirtualFree(m_pBase, 0, MEM_RELEASE);
  5227.     }
  5228. #if !defined(_WIN32_WCE)
  5229.     int Except(LPEXCEPTION_POINTERS lpEP)
  5230.     {
  5231.         EXCEPTION_RECORD* pExcept = lpEP->ExceptionRecord;
  5232.         if (pExcept->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
  5233.             return EXCEPTION_CONTINUE_SEARCH;
  5234.         BYTE* pAddress = (LPBYTE) pExcept->ExceptionInformation[1];
  5235.         VirtualAlloc(pAddress, ((BYTE*)m_pTop - (BYTE*)m_pBase), MEM_COMMIT, PAGE_READWRITE);
  5236.         return EXCEPTION_CONTINUE_EXECUTION;
  5237.     }
  5238. #endif // _WIN32_WCE
  5239.     void Seek(int nElement)
  5240.     {
  5241.         m_pCurrent = &m_pBase[nElement];
  5242.     }
  5243.     void SetAt(int nElement, const T& Element)
  5244.     {
  5245.         __try
  5246.         {
  5247.             T* p = &m_pBase[nElement]
  5248.             *p = Element;
  5249.             m_pTop = p > m_pTop ? p : m_pTop;
  5250.         }
  5251.         __except(Except(GetExceptionInformation()))
  5252.         {
  5253.         }
  5254.  
  5255.     }
  5256.     template <class Q>
  5257.     void WriteBulk(Q& helper)
  5258.     {
  5259.         __try
  5260.         {
  5261.             m_pCurrent = helper(m_pBase);
  5262.             m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;
  5263.         }
  5264.         __except(Except(GetExceptionInformation()))
  5265.         {
  5266.         }
  5267.     }
  5268.     void Write(const T& Element)
  5269.     {
  5270.         __try
  5271.         {
  5272.             *m_pCurrent = Element;
  5273.             m_pCurrent++;
  5274.             m_pTop = m_pCurrent > m_pTop ? m_pCurrent : m_pTop;
  5275.         }
  5276.         __except(Except(GetExceptionInformation()))
  5277.         {
  5278.         }
  5279.     }
  5280.     T& Read()
  5281.     {
  5282.         return *m_pCurrent;
  5283.     }
  5284.     operator BSTR()
  5285.     {
  5286.         BSTR bstrTemp;
  5287.         __try
  5288.         {
  5289.             bstrTemp = SysAllocStringByteLen((char*) m_pBase,
  5290.                 (UINT) ((BYTE*)m_pTop - (BYTE*)m_pBase));
  5291.         }
  5292.         __except(Except(GetExceptionInformation()))
  5293.         {
  5294.         }
  5295.         return bstrTemp;
  5296.     }
  5297.     const T& operator[](int nElement) const
  5298.     {
  5299.         return m_pBase[nElement];
  5300.     }
  5301.     operator T*()
  5302.     {
  5303.         return m_pBase;
  5304.     }
  5305. };
  5306.  
  5307. typedef CVirtualBuffer<BYTE> CVirtualBytes;
  5308.  
  5309.  
  5310. inline HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr)
  5311. {
  5312.     if (atlTraceQI & ATL_TRACE_CATEGORY)
  5313.     {
  5314.         USES_CONVERSION;
  5315.         CRegKey key;
  5316.         TCHAR szName[100];
  5317.         DWORD dwType,dw = sizeof(szName);
  5318.  
  5319.         LPOLESTR pszGUID = NULL;
  5320.         StringFromCLSID(iid, &pszGUID);
  5321.         OutputDebugString(pszClassName);
  5322.         OutputDebugString(_T(" - "));
  5323.  
  5324.         // Attempt to find it in the interfaces section
  5325.         key.Open(HKEY_CLASSES_ROOT, _T("Interface"), KEY_READ);
  5326.         if (key.Open(key, OLE2T(pszGUID), KEY_READ) == S_OK)
  5327.         {
  5328.             *szName = 0;
  5329.             RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
  5330.             OutputDebugString(szName);
  5331.             goto cleanup;
  5332.         }
  5333.         // Attempt to find it in the clsid section
  5334.         key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ);
  5335.         if (key.Open(key, OLE2T(pszGUID), KEY_READ) == S_OK)
  5336.         {
  5337.             *szName = 0;
  5338.             RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
  5339.             OutputDebugString(_T("(CLSID\?\?\?) "));
  5340.             OutputDebugString(szName);
  5341.             goto cleanup;
  5342.         }
  5343.         OutputDebugString(OLE2T(pszGUID));
  5344.     cleanup:
  5345.         if (hr != S_OK)
  5346.             OutputDebugString(_T(" - failed"));
  5347.         OutputDebugString(_T("\n"));
  5348.         CoTaskMemFree(pszGUID);
  5349.     }
  5350.     return hr;
  5351. }
  5352.  
  5353. #pragma pack(pop)
  5354.  
  5355. // WM_FORWARDMSG - used to forward a message to another window for processing
  5356. // WPARAM - DWORD dwUserData - defined by user
  5357. // LPARAM - LPMSG pMsg - a pointer to the MSG structure
  5358. // return value - 0 if the message was not processed, nonzero if it was
  5359. #define WM_FORWARDMSG        0x037F
  5360.  
  5361. }; //namespace ATL
  5362. using namespace ATL;
  5363.  
  5364. //only suck in definition if static linking
  5365. #ifndef _ATL_DLL_IMPL
  5366. #ifndef _ATL_DLL
  5367. #define _ATLBASE_IMPL
  5368. #endif
  5369. #endif
  5370.  
  5371. #endif // __ATLBASE_H__
  5372.  
  5373. //All exports go here
  5374. #ifdef _ATLBASE_IMPL
  5375.  
  5376. #ifndef _ATL_DLL_IMPL
  5377. namespace ATL
  5378. {
  5379. #endif
  5380.  
  5381. /////////////////////////////////////////////////////////////////////////////
  5382. // statics
  5383.  
  5384. static UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName)
  5385. {
  5386.     ATLASSERT(lpszPathName != NULL);
  5387.  
  5388.     // always capture the complete file name including extension (if present)
  5389.     LPCOLESTR lpszTemp = lpszPathName;
  5390.     for (LPCOLESTR lpsz = lpszPathName; *lpsz != NULL; )
  5391.     {
  5392.         LPCOLESTR lp = CharNextO(lpsz);
  5393.         // remember last directory/drive separator
  5394.         if (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))
  5395.             lpszTemp = lp;
  5396.         lpsz = lp;
  5397.     }
  5398.  
  5399.     return lpszTemp-lpszPathName;
  5400. }
  5401.  
  5402. /////////////////////////////////////////////////////////////////////////////
  5403. // QI support
  5404.  
  5405. ATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,
  5406.     const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
  5407. {
  5408.     ATLASSERT(pThis != NULL);
  5409.     // First entry in the com map should be a simple map entry
  5410.     ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
  5411.     if (ppvObject == NULL)
  5412.         return E_POINTER;
  5413.     *ppvObject = NULL;
  5414.     if (InlineIsEqualUnknown(iid)) // use first interface
  5415.     {
  5416.             IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
  5417.             pUnk->AddRef();
  5418.             *ppvObject = pUnk;
  5419.             return S_OK;
  5420.     }
  5421.     while (pEntries->pFunc != NULL)
  5422.     {
  5423.         BOOL bBlind = (pEntries->piid == NULL);
  5424.         if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
  5425.         {
  5426.             if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
  5427.             {
  5428.                 ATLASSERT(!bBlind);
  5429.                 IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
  5430.                 pUnk->AddRef();
  5431.                 *ppvObject = pUnk;
  5432.                 return S_OK;
  5433.             }
  5434.             else //actual function call
  5435.             {
  5436.                 HRESULT hRes = pEntries->pFunc(pThis,
  5437.                     iid, ppvObject, pEntries->dw);
  5438.                 if (hRes == S_OK || (!bBlind && FAILED(hRes)))
  5439.                     return hRes;
  5440.             }
  5441.         }
  5442.         pEntries++;
  5443.     }
  5444.     return E_NOINTERFACE;
  5445. }
  5446.  
  5447. /////////////////////////////////////////////////////////////////////////////
  5448. // Smart Pointer helpers
  5449.  
  5450. ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
  5451. {
  5452.     if (lp != NULL)
  5453.         lp->AddRef();
  5454.     if (*pp)
  5455.         (*pp)->Release();
  5456.     *pp = lp;
  5457.     return lp;
  5458. }
  5459.  
  5460. ATLINLINE ATLAPI_(IUnknown*) AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
  5461. {
  5462.     IUnknown* pTemp = *pp;
  5463.     *pp = NULL;
  5464.     if (lp != NULL)
  5465.         lp->QueryInterface(riid, (void**)pp);
  5466.     if (pTemp)
  5467.         pTemp->Release();
  5468.     return *pp;
  5469. }
  5470.  
  5471. #if !defined(_WIN32_WCE)
  5472. /////////////////////////////////////////////////////////////////////////////
  5473. // Inproc Marshaling helpers
  5474.  
  5475. //This API should be called from the same thread that called
  5476. //AtlMarshalPtrInProc
  5477. ATLINLINE ATLAPI AtlFreeMarshalStream(IStream* pStream)
  5478. {
  5479.     if (pStream != NULL)
  5480.     {
  5481.         LARGE_INTEGER l;
  5482.         l.QuadPart = 0;
  5483.         pStream->Seek(l, STREAM_SEEK_SET, NULL);
  5484.         CoReleaseMarshalData(pStream);
  5485.         pStream->Release();
  5486.     }
  5487.     return S_OK;
  5488. }
  5489.  
  5490. ATLINLINE ATLAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream)
  5491. {
  5492.     HRESULT hRes = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
  5493.     if (SUCCEEDED(hRes))
  5494.     {
  5495.         hRes = CoMarshalInterface(*ppStream, iid,
  5496.             pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
  5497.         if (FAILED(hRes))
  5498.         {
  5499.             (*ppStream)->Release();
  5500.             *ppStream = NULL;
  5501.         }
  5502.     }
  5503.     return hRes;
  5504. }
  5505.  
  5506. ATLINLINE ATLAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk)
  5507. {
  5508.     *ppUnk = NULL;
  5509.     HRESULT hRes = E_INVALIDARG;
  5510.     if (pStream != NULL)
  5511.     {
  5512.         LARGE_INTEGER l;
  5513.         l.QuadPart = 0;
  5514.         pStream->Seek(l, STREAM_SEEK_SET, NULL);
  5515.         hRes = CoUnmarshalInterface(pStream, iid, (void**)ppUnk);
  5516.     }
  5517.     return hRes;
  5518. }
  5519.  
  5520. ATLINLINE ATLAPI_(BOOL) AtlWaitWithMessageLoop(HANDLE hEvent)
  5521. {
  5522.     DWORD dwRet;
  5523.     MSG msg;
  5524.  
  5525.     while(1)
  5526.     {
  5527.         dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, INFINITE, QS_ALLINPUT);
  5528.  
  5529.         if (dwRet == WAIT_OBJECT_0)
  5530.             return TRUE;    // The event was signaled
  5531.  
  5532.         if (dwRet != WAIT_OBJECT_0 + 1)
  5533.             break;          // Something else happened
  5534.  
  5535.         // There is one or more window message available. Dispatch them
  5536.         while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
  5537.         {
  5538.             TranslateMessage(&msg);
  5539.             DispatchMessage(&msg);
  5540.             if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
  5541.                 return TRUE; // Event is now signaled.
  5542.         }
  5543.     }
  5544.     return FALSE;
  5545. }
  5546. #endif // _WIN32_WCE
  5547.  
  5548. /////////////////////////////////////////////////////////////////////////////
  5549. // Connection Point Helpers
  5550.  
  5551. ATLINLINE ATLAPI AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  5552. {
  5553.     CComPtr<IConnectionPointContainer> pCPC;
  5554.     CComPtr<IConnectionPoint> pCP;
  5555.     HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  5556.     if (SUCCEEDED(hRes))
  5557.         hRes = pCPC->FindConnectionPoint(iid, &pCP);
  5558.     if (SUCCEEDED(hRes))
  5559.         hRes = pCP->Advise(pUnk, pdw);
  5560.     return hRes;
  5561. }
  5562.  
  5563. ATLINLINE ATLAPI AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
  5564. {
  5565.     CComPtr<IConnectionPointContainer> pCPC;
  5566.     CComPtr<IConnectionPoint> pCP;
  5567.     HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  5568.     if (SUCCEEDED(hRes))
  5569.         hRes = pCPC->FindConnectionPoint(iid, &pCP);
  5570.     if (SUCCEEDED(hRes))
  5571.         hRes = pCP->Unadvise(dw);
  5572.     return hRes;
  5573. }
  5574.  
  5575. /////////////////////////////////////////////////////////////////////////////
  5576. // IDispatch Error handling
  5577.  
  5578. ATLINLINE ATLAPI AtlSetErrorInfo(const CLSID& clsid, LPCOLESTR lpszDesc, DWORD dwHelpID,
  5579.     LPCOLESTR lpszHelpFile, const IID& iid, HRESULT hRes, HINSTANCE hInst)
  5580. {
  5581.     USES_CONVERSION;
  5582.     TCHAR szDesc[1024];
  5583.     szDesc[0] = NULL;
  5584.     // For a valid HRESULT the id should be in the range [0x0200, 0xffff]
  5585.     if (HIWORD(lpszDesc) == 0) //id
  5586.     {
  5587.         UINT nID = LOWORD((DWORD)lpszDesc);
  5588.         ATLASSERT((nID >= 0x0200 && nID <= 0xffff) || hRes != 0);
  5589.         if (LoadString(hInst, nID, szDesc, 1024) == 0)
  5590.         {
  5591.             ATLASSERT(FALSE);
  5592.             lstrcpy(szDesc, _T("Unknown Error"));
  5593.         }
  5594.         lpszDesc = T2OLE(szDesc);
  5595.         if (hRes == 0)
  5596.             hRes = MAKE_HRESULT(3, FACILITY_ITF, nID);
  5597.     }
  5598.  
  5599.     CComPtr<ICreateErrorInfo> pICEI;
  5600.     if (SUCCEEDED(CreateErrorInfo(&pICEI)))
  5601.     {
  5602.         CComPtr<IErrorInfo> pErrorInfo;
  5603.         pICEI->SetGUID(iid);
  5604.         LPOLESTR lpsz;
  5605.         WCE_FCTN(ProgIDFromCLSID)(clsid, &lpsz);
  5606.         if (lpsz != NULL)
  5607.             pICEI->SetSource(lpsz);
  5608.         if (dwHelpID != 0 && lpszHelpFile != NULL)
  5609.         {
  5610.             pICEI->SetHelpContext(dwHelpID);
  5611.             pICEI->SetHelpFile(const_cast<LPOLESTR>(lpszHelpFile));
  5612.         }
  5613.         CoTaskMemFree(lpsz);
  5614.         pICEI->SetDescription((LPOLESTR)lpszDesc);
  5615.         if (SUCCEEDED(pICEI->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo)))
  5616.             SetErrorInfo(0, pErrorInfo);
  5617.     }
  5618.     return (hRes == 0) ? DISP_E_EXCEPTION : hRes;
  5619. }
  5620.  
  5621. /////////////////////////////////////////////////////////////////////////////
  5622. // Module
  5623.  
  5624. struct _ATL_MODULE20
  5625. {
  5626. // Attributes
  5627. public:
  5628.     UINT cbSize;
  5629.     HINSTANCE m_hInst;
  5630.     HINSTANCE m_hInstResource;
  5631.     HINSTANCE m_hInstTypeLib;
  5632.     _ATL_OBJMAP_ENTRY* m_pObjMap;
  5633.     LONG m_nLockCnt;
  5634.     HANDLE m_hHeap;
  5635.     CRITICAL_SECTION m_csTypeInfoHolder;
  5636.     CRITICAL_SECTION m_csWindowCreate;
  5637.     CRITICAL_SECTION m_csObjMap;
  5638. };
  5639.  
  5640. typedef _ATL_MODULE _ATL_MODULE30;
  5641.  
  5642. struct _ATL_OBJMAP_ENTRY20
  5643. {
  5644.     const CLSID* pclsid;
  5645.     HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
  5646.     _ATL_CREATORFUNC* pfnGetClassObject;
  5647.     _ATL_CREATORFUNC* pfnCreateInstance;
  5648.     IUnknown* pCF;
  5649.     DWORD dwRegister;
  5650.     _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
  5651. };
  5652.  
  5653. typedef _ATL_OBJMAP_ENTRY _ATL_OBJMAP_ENTRY30;
  5654.  
  5655. inline _ATL_OBJMAP_ENTRY* _NextObjectMapEntry(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* pEntry)
  5656. {
  5657.     if (pM->cbSize == sizeof(_ATL_MODULE20))
  5658.         return (_ATL_OBJMAP_ENTRY*)(((BYTE*)pEntry) + sizeof(_ATL_OBJMAP_ENTRY20));
  5659.     return pEntry+1;
  5660. }
  5661.  
  5662. //Although these functions are big, they are only used once in a module
  5663. //so we should make them inline.
  5664.  
  5665. ATLINLINE ATLAPI AtlModuleInit(_ATL_MODULE* pM, _ATL_OBJMAP_ENTRY* p, HINSTANCE h)
  5666. {
  5667.     ATLASSERT(pM != NULL);
  5668.     if (pM == NULL)
  5669.         return E_INVALIDARG;
  5670. #ifdef _ATL_DLL_IMPL
  5671.     if ((pM->cbSize != _nAtlModuleVer1Size) && (pM->cbSize != sizeof(_ATL_MODULE)))
  5672.         return E_INVALIDARG;
  5673. #else
  5674.     ATLASSERT(pM->cbSize == sizeof(_ATL_MODULE));
  5675. #endif
  5676.     pM->m_pObjMap = p;
  5677.     pM->m_hInst = pM->m_hInstTypeLib = pM->m_hInstResource = h;
  5678.     pM->m_nLockCnt=0L;
  5679.     pM->m_hHeap = NULL;
  5680.     InitializeCriticalSection(&pM->m_csTypeInfoHolder);
  5681.     InitializeCriticalSection(&pM->m_csWindowCreate);
  5682.     InitializeCriticalSection(&pM->m_csObjMap);
  5683. #ifdef _ATL_DLL_IMPL
  5684.     if (pM->cbSize > _nAtlModuleVer1Size)
  5685. #endif
  5686.     {
  5687.         pM->m_pCreateWndList = NULL;
  5688.         pM->m_bDestroyHeap = true;
  5689.         pM->m_dwHeaps = 0;
  5690.         pM->m_nHeap = 0;
  5691.         pM->m_phHeaps = NULL;
  5692.         pM->m_pTermFuncs = NULL;
  5693.         if (pM->m_pObjMap != NULL)
  5694.         {
  5695.             _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5696.             while (pEntry->pclsid != NULL)
  5697.             {
  5698.                 pEntry->pfnObjectMain(true); //initialize class resources
  5699.                 pEntry = _NextObjectMapEntry(pM, pEntry);
  5700.             }
  5701.         }
  5702.     }
  5703.     
  5704.     return S_OK;
  5705. }
  5706.  
  5707. #if !defined(_WIN32_WCE)
  5708. ATLINLINE ATLAPI AtlModuleRegisterClassObjects(_ATL_MODULE* pM, DWORD dwClsContext, DWORD dwFlags)
  5709. {
  5710.     ATLASSERT(pM != NULL);
  5711.     if (pM == NULL)
  5712.         return E_INVALIDARG;
  5713.     ATLASSERT(pM->m_pObjMap != NULL);
  5714.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5715.     HRESULT hRes = S_OK;
  5716.     while (pEntry->pclsid != NULL && hRes == S_OK)
  5717.     {
  5718.         hRes = pEntry->RegisterClassObject(dwClsContext, dwFlags);
  5719.         pEntry = _NextObjectMapEntry(pM, pEntry);
  5720.     }
  5721.     return hRes;
  5722. }
  5723.  
  5724. ATLINLINE ATLAPI AtlModuleRevokeClassObjects(_ATL_MODULE* pM)
  5725. {
  5726.     ATLASSERT(pM != NULL);
  5727.     if (pM == NULL)
  5728.         return E_INVALIDARG;
  5729.     ATLASSERT(pM->m_pObjMap != NULL);
  5730.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5731.     HRESULT hRes = S_OK;
  5732.     while (pEntry->pclsid != NULL && hRes == S_OK)
  5733.     {
  5734.         hRes = pEntry->RevokeClassObject();
  5735.         pEntry = _NextObjectMapEntry(pM, pEntry);
  5736.     }
  5737.     return hRes;
  5738. }
  5739. #endif // _WIN32_WCE
  5740.  
  5741. ATLINLINE ATLAPI AtlModuleGetClassObject(_ATL_MODULE* pM, REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  5742. {
  5743.     ATLASSERT(pM != NULL);
  5744.     if (pM == NULL)
  5745.         return E_INVALIDARG;
  5746.     ATLASSERT(pM->m_pObjMap != NULL);
  5747.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5748.     HRESULT hRes = S_OK;
  5749.     if (ppv == NULL)
  5750.         return E_POINTER;
  5751.     *ppv = NULL;
  5752.     while (pEntry->pclsid != NULL)
  5753.     {
  5754.         if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
  5755.         {
  5756.             if (pEntry->pCF == NULL)
  5757.             {
  5758.                 EnterCriticalSection(&pM->m_csObjMap);
  5759.                 if (pEntry->pCF == NULL)
  5760.                     hRes = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, IID_IUnknown, (LPVOID*)&pEntry->pCF);
  5761.                 LeaveCriticalSection(&pM->m_csObjMap);
  5762.             }
  5763.             if (pEntry->pCF != NULL)
  5764.                 hRes = pEntry->pCF->QueryInterface(riid, ppv);
  5765.             break;
  5766.         }
  5767.         pEntry = _NextObjectMapEntry(pM, pEntry);
  5768.     }
  5769.     if (*ppv == NULL && hRes == S_OK)
  5770.         hRes = CLASS_E_CLASSNOTAVAILABLE;
  5771.     return hRes;
  5772. }
  5773.  
  5774. ATLINLINE ATLAPI AtlModuleTerm(_ATL_MODULE* pM)
  5775. {
  5776.     ATLASSERT(pM != NULL);
  5777.     if (pM == NULL)
  5778.         return E_INVALIDARG;
  5779.     ATLASSERT(pM->m_hInst != NULL);
  5780.     if (pM->m_pObjMap != NULL)
  5781.     {
  5782.         _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5783.         while (pEntry->pclsid != NULL)
  5784.         {
  5785.             if (pEntry->pCF != NULL)
  5786.                 pEntry->pCF->Release();
  5787.             pEntry->pCF = NULL;
  5788. #ifdef _ATL_DLL_IMPL
  5789.             if (pM->cbSize > _nAtlModuleVer1Size)
  5790. #endif
  5791.                 pEntry->pfnObjectMain(false); //cleanup class resources
  5792.             pEntry = _NextObjectMapEntry(pM, pEntry);
  5793.         }
  5794.     }
  5795.     DeleteCriticalSection(&pM->m_csTypeInfoHolder);
  5796.     DeleteCriticalSection(&pM->m_csWindowCreate);
  5797.     DeleteCriticalSection(&pM->m_csObjMap);
  5798.  
  5799. #ifdef _ATL_DLL_IMPL
  5800.     if (pM->cbSize > _nAtlModuleVer1Size)
  5801. #endif
  5802.     {
  5803.         _ATL_TERMFUNC_ELEM* pElem = pM->m_pTermFuncs;
  5804.         _ATL_TERMFUNC_ELEM* pNext = NULL;
  5805.         while (pElem != NULL)
  5806.         {
  5807.             pElem->pFunc(pElem->dw);
  5808.             pNext = pElem->pNext;
  5809.             delete pElem;
  5810.             pElem = pNext;
  5811.         }
  5812.         if (pM->m_hHeap != NULL && pM->m_bDestroyHeap)
  5813.         {
  5814. #ifndef _ATL_NO_MP_HEAP
  5815.             if (pM->m_phHeaps != NULL)
  5816.             {
  5817.                 for (DWORD i=0; i<=pM->m_dwHeaps; i++)
  5818.                     HeapDestroy(pM->m_phHeaps[i]);
  5819.             }
  5820. #endif
  5821.             HeapDestroy(pM->m_hHeap);
  5822.         }
  5823.     }
  5824.     return S_OK;
  5825. }
  5826.  
  5827. ATLINLINE ATLAPI AtlModuleAddTermFunc(_ATL_MODULE* pM, _ATL_TERMFUNC* pFunc, DWORD dw)
  5828. {
  5829.     HRESULT hr = S_OK;
  5830.     _ATL_TERMFUNC_ELEM* pNew = NULL;
  5831.     ATLTRY(pNew = new _ATL_TERMFUNC_ELEM);
  5832.     if (pNew == NULL)
  5833.         hr = E_OUTOFMEMORY;
  5834.     else
  5835.     {
  5836.         pNew->pFunc = pFunc;
  5837.         pNew->dw = dw;
  5838.         EnterCriticalSection(&pM->m_csStaticDataInit);
  5839.         pNew->pNext = pM->m_pTermFuncs;
  5840.         pM->m_pTermFuncs = pNew;
  5841.         LeaveCriticalSection(&pM->m_csStaticDataInit);
  5842.     }
  5843.     return hr;
  5844. }
  5845.  
  5846. #if !defined(_WIN32_WCE)
  5847. ATLINLINE ATLAPI AtlRegisterClassCategoriesHelper( REFCLSID clsid, 
  5848.    const struct _ATL_CATMAP_ENTRY* pCatMap, BOOL bRegister )
  5849. {
  5850.    CComPtr< ICatRegister > pCatRegister;
  5851.    HRESULT hResult;
  5852.    const struct _ATL_CATMAP_ENTRY* pEntry;
  5853.    CATID catid;
  5854.  
  5855.    if( pCatMap == NULL )
  5856.    {
  5857.       return( S_OK );
  5858.    }
  5859.  
  5860.    hResult = CoCreateInstance( CLSID_StdComponentCategoriesMgr, NULL, 
  5861.       CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pCatRegister );
  5862.    if( FAILED( hResult ) )
  5863.    {
  5864.       // Since not all systems have the category manager installed, we'll allow
  5865.       // the registration to succeed even though we didn't register our 
  5866.       // categories.  If you really want to register categories on a system
  5867.       // without the category manager, you can either manually add the 
  5868.       // appropriate entries to your registry script (.rgs), or you can 
  5869.       // redistribute comcat.dll.
  5870.       return( S_OK );
  5871.    }
  5872.  
  5873.    hResult = S_OK;
  5874.    pEntry = pCatMap;
  5875.    while( pEntry->iType != _ATL_CATMAP_ENTRY_END )
  5876.    {
  5877.       catid = *pEntry->pcatid;
  5878.       if( bRegister )
  5879.       {
  5880.          if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED )
  5881.          {
  5882.             hResult = pCatRegister->RegisterClassImplCategories( clsid, 1, 
  5883.                &catid );
  5884.          }
  5885.          else
  5886.          {
  5887.             ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );
  5888.             hResult = pCatRegister->RegisterClassReqCategories( clsid, 1, 
  5889.                &catid );
  5890.          }
  5891.          if( FAILED( hResult ) )
  5892.          {
  5893.             return( hResult );
  5894.          }
  5895.       }
  5896.       else
  5897.       {
  5898.          if( pEntry->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED )
  5899.          {
  5900.             pCatRegister->UnRegisterClassImplCategories( clsid, 1, &catid );
  5901.          }
  5902.          else
  5903.          {
  5904.             ATLASSERT( pEntry->iType == _ATL_CATMAP_ENTRY_REQUIRED );
  5905.             pCatRegister->UnRegisterClassReqCategories( clsid, 1, &catid );
  5906.          }
  5907.       }
  5908.       pEntry++;
  5909.    }
  5910.  
  5911.    return( S_OK );
  5912. }
  5913. #endif // _WIN32_WCE
  5914.  
  5915. ATLINLINE ATLAPI AtlModuleRegisterServer(_ATL_MODULE* pM, BOOL bRegTypeLib, const CLSID* pCLSID)
  5916. {
  5917.     ATLASSERT(pM != NULL);
  5918.     if (pM == NULL)
  5919.         return E_INVALIDARG;
  5920.     ATLASSERT(pM->m_hInst != NULL);
  5921.     ATLASSERT(pM->m_pObjMap != NULL);
  5922.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5923.     HRESULT hRes = S_OK;
  5924.     for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry))
  5925.     {
  5926.         if (pCLSID == NULL)
  5927.         {
  5928.             if (pEntry->pfnGetObjectDescription != NULL &&
  5929.                 pEntry->pfnGetObjectDescription() != NULL)
  5930.                     continue;
  5931.         }
  5932.         else
  5933.         {
  5934.             if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
  5935.                 continue;
  5936.         }
  5937.         hRes = pEntry->pfnUpdateRegistry(TRUE);
  5938.         if (FAILED(hRes))
  5939.             break;
  5940. #if !defined(_WIN32_WCE)
  5941.         if (pM->cbSize == sizeof(_ATL_MODULE))
  5942.         {
  5943.             hRes = AtlRegisterClassCategoriesHelper( *pEntry->pclsid, 
  5944.                 pEntry->pfnGetCategoryMap(), TRUE );
  5945.             if (FAILED(hRes))
  5946.                 break;
  5947.         }
  5948. #endif // _WIN32_WCE
  5949.     }
  5950.     if (SUCCEEDED(hRes) && bRegTypeLib)
  5951.         hRes = AtlModuleRegisterTypeLib(pM, 0);
  5952.     return hRes;
  5953. }
  5954.  
  5955. ATLINLINE ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID)
  5956. {
  5957.     ATLASSERT(pM != NULL);
  5958.     if (pM == NULL)
  5959.         return E_INVALIDARG;
  5960.     ATLASSERT(pM->m_hInst != NULL);
  5961.     ATLASSERT(pM->m_pObjMap != NULL);
  5962.     _ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
  5963.     for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry))
  5964.     {
  5965.         if (pCLSID == NULL)
  5966.         {
  5967.             if (pEntry->pfnGetObjectDescription != NULL
  5968.                 && pEntry->pfnGetObjectDescription() != NULL)
  5969.                 continue;
  5970.         }
  5971.         else
  5972.         {
  5973.             if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
  5974.                 continue;
  5975.         }
  5976.         pEntry->pfnUpdateRegistry(FALSE); //unregister
  5977. #if !defined(_WIN32_WCE)
  5978.         AtlRegisterClassCategoriesHelper( *pEntry->pclsid, 
  5979.             pEntry->pfnGetCategoryMap(), FALSE );
  5980. #endif // _WIN32_WCE
  5981.     }
  5982.     if (bUnRegTypeLib)
  5983.         AtlModuleUnRegisterTypeLib(pM, 0);
  5984.     return S_OK;
  5985. }
  5986.  
  5987. ATLINLINE ATLAPI AtlModuleUnregisterServer(_ATL_MODULE* pM, const CLSID* pCLSID)
  5988. {
  5989.     return AtlModuleUnregisterServerEx(pM, FALSE, pCLSID);
  5990. }
  5991.  
  5992. ATLINLINE ATLAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULE* pM, LPCOLESTR lpszRes,
  5993.     BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
  5994. {
  5995.     USES_CONVERSION;
  5996.     ATLASSERT(pM != NULL);
  5997.     HRESULT hRes = S_OK;
  5998.     CComPtr<IRegistrar> p;
  5999.     if (pReg != NULL)
  6000.         p = pReg;
  6001.     else
  6002.     {
  6003.         hRes = CoCreateInstance(CLSID_Registrar, NULL,
  6004.             CLSCTX_INPROC_SERVER, IID_IRegistrar, (void**)&p);
  6005.     }
  6006.     if (SUCCEEDED(hRes))
  6007.     {
  6008.         TCHAR szModule[_MAX_PATH];
  6009.         GetModuleFileName(pM->m_hInst, szModule, _MAX_PATH);
  6010.  
  6011.       // Convert to short path to work around bug in NT4's CreateProcess
  6012.       WCE_DEL TCHAR szModuleShort[_MAX_PATH];
  6013.       WCE_DEL GetShortPathName(szModule, szModuleShort, _MAX_PATH);
  6014.       LPOLESTR pszModule = T2OLE(WCE_IF(szModule,szModuleShort));
  6015.  
  6016.         int nLen = ocslen(pszModule);
  6017.         LPOLESTR pszModuleQuote = (LPOLESTR)alloca((nLen*2+1)*sizeof(OLECHAR));
  6018.         CComModule::ReplaceSingleQuote(pszModuleQuote, pszModule);
  6019.         p->AddReplacement(OLESTR("Module"), pszModuleQuote);
  6020.  
  6021.         if (NULL != pMapEntries)
  6022.         {
  6023.             while (NULL != pMapEntries->szKey)
  6024.             {
  6025.                 ATLASSERT(NULL != pMapEntries->szData);
  6026.                 p->AddReplacement((LPOLESTR)pMapEntries->szKey, (LPOLESTR)pMapEntries->szData);
  6027.                 pMapEntries++;
  6028.             }
  6029.         }
  6030.         LPCOLESTR szType = OLESTR("REGISTRY");
  6031.         if (HIWORD(lpszRes)==0)
  6032.         {
  6033.             if (bRegister)
  6034.                 hRes = p->ResourceRegister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);
  6035.             else
  6036.                 hRes = p->ResourceUnregister(pszModule, ((UINT)LOWORD((DWORD)lpszRes)), szType);
  6037.         }
  6038.         else
  6039.         {
  6040.             if (bRegister)
  6041.                 hRes = p->ResourceRegisterSz(pszModule, lpszRes, szType);
  6042.             else
  6043.                 hRes = p->ResourceUnregisterSz(pszModule, lpszRes, szType);
  6044.         }
  6045.  
  6046.     }
  6047.     return hRes;
  6048. }
  6049.  
  6050. /////////////////////////////////////////////////////////////////////////////
  6051. // TypeLib Support
  6052.  
  6053. ATLINLINE ATLAPI AtlModuleLoadTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex, BSTR* pbstrPath, ITypeLib** ppTypeLib)
  6054. {
  6055.     *pbstrPath = NULL;
  6056.     *ppTypeLib = NULL;
  6057.     ATLASSERT(pM != NULL);
  6058.     USES_CONVERSION;
  6059.     ATLASSERT(pM->m_hInstTypeLib != NULL);
  6060.     TCHAR szModule[_MAX_PATH+10];
  6061.     GetModuleFileName(pM->m_hInstTypeLib, szModule, _MAX_PATH);
  6062.     if (lpszIndex != NULL)
  6063.         lstrcat(szModule, OLE2CT(lpszIndex));
  6064.     LPOLESTR lpszModule = T2OLE(szModule);
  6065.     HRESULT hr = LoadTypeLib(lpszModule, ppTypeLib);
  6066.     if (!SUCCEEDED(hr))
  6067.     {
  6068.         // typelib not in module, try <module>.tlb instead
  6069.         LPTSTR lpszExt = NULL;
  6070.         LPTSTR lpsz;
  6071.         for (lpsz = szModule; *lpsz != NULL; lpsz = CharNext(lpsz))
  6072.         {
  6073.             if (*lpsz == _T('.'))
  6074.                 lpszExt = lpsz;
  6075.         }
  6076.         if (lpszExt == NULL)
  6077.             lpszExt = lpsz;
  6078.         lstrcpy(lpszExt, _T(".tlb"));
  6079.         lpszModule = T2OLE(szModule);
  6080.         hr = LoadTypeLib(lpszModule, ppTypeLib);
  6081.     }
  6082.     if (SUCCEEDED(hr))
  6083.         *pbstrPath = OLE2BSTR(lpszModule);
  6084.     return hr;
  6085. }
  6086.  
  6087. ATLINLINE ATLAPI AtlModuleUnRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex)
  6088. {
  6089.     typedef HRESULT (WINAPI *PFNRTL)(REFGUID, WORD, WORD, LCID, SYSKIND);
  6090.     CComBSTR bstrPath;
  6091.     CComPtr<ITypeLib> pTypeLib;
  6092.     HRESULT hr = AtlModuleLoadTypeLib(pM, lpszIndex, &bstrPath, &pTypeLib);
  6093.     if (SUCCEEDED(hr))
  6094.     {
  6095.         TLIBATTR* ptla;
  6096.         HRESULT hr = pTypeLib->GetLibAttr(&ptla);
  6097.         if (SUCCEEDED(hr))
  6098.         {
  6099.             HINSTANCE h = LoadLibrary(_T("oleaut32.dll"));
  6100.             if (h != NULL)
  6101.             {
  6102.                 PFNRTL pfn = (PFNRTL) GetProcAddress(h, WCE_IF(_T("UnRegisterTypeLib"),"UnRegisterTypeLib"));
  6103.                 if (pfn != NULL)
  6104.                     hr = pfn(ptla->guid, ptla->wMajorVerNum, ptla->wMinorVerNum, ptla->lcid, ptla->syskind);
  6105.                 FreeLibrary(h);
  6106.             }
  6107.             pTypeLib->ReleaseTLibAttr(ptla);
  6108.         }
  6109.     }
  6110.     return hr;
  6111. }
  6112.  
  6113. ATLINLINE ATLAPI AtlModuleRegisterTypeLib(_ATL_MODULE* pM, LPCOLESTR lpszIndex)
  6114. {
  6115.     CComBSTR bstrPath;
  6116.     CComPtr<ITypeLib> pTypeLib;
  6117.     HRESULT hr = AtlModuleLoadTypeLib(pM, lpszIndex, &bstrPath, &pTypeLib);
  6118.     if (SUCCEEDED(hr))
  6119.     {
  6120.         OLECHAR szDir[_MAX_PATH];
  6121.         ocscpy(szDir, bstrPath);
  6122.         szDir[AtlGetDirLen(szDir)] = 0;
  6123.         hr = ::RegisterTypeLib(pTypeLib, bstrPath, szDir);
  6124.     }
  6125.     return hr;
  6126. }
  6127.  
  6128. ATLINLINE ATLAPI_(DWORD) AtlGetVersion(void* /* pReserved */)
  6129. {
  6130.     return _ATL_VER;
  6131. }
  6132.  
  6133. ATLINLINE ATLAPI_(void) AtlModuleAddCreateWndData(_ATL_MODULE* pM, _AtlCreateWndData* pData, void* pObject)
  6134. {
  6135.     pData->m_pThis = pObject;
  6136.     pData->m_dwThreadID = ::GetCurrentThreadId();
  6137.     ::EnterCriticalSection(&pM->m_csWindowCreate);
  6138.     pData->m_pNext = pM->m_pCreateWndList;
  6139.     pM->m_pCreateWndList = pData;
  6140.     ::LeaveCriticalSection(&pM->m_csWindowCreate);
  6141. }
  6142.  
  6143. ATLINLINE ATLAPI_(void*) AtlModuleExtractCreateWndData(_ATL_MODULE* pM)
  6144. {
  6145.     void* pv = NULL;
  6146.     ::EnterCriticalSection(&pM->m_csWindowCreate);
  6147.     _AtlCreateWndData* pEntry = pM->m_pCreateWndList;
  6148.     if(pEntry != NULL)
  6149.     {
  6150.         DWORD dwThreadID = ::GetCurrentThreadId();
  6151.         _AtlCreateWndData* pPrev = NULL;
  6152.         while(pEntry != NULL)
  6153.         {
  6154.             if(pEntry->m_dwThreadID == dwThreadID)
  6155.             {
  6156.                 if(pPrev == NULL)
  6157.                     pM->m_pCreateWndList = pEntry->m_pNext;
  6158.                 else
  6159.                     pPrev->m_pNext = pEntry->m_pNext;
  6160.                 pv = pEntry->m_pThis;
  6161.                 break;
  6162.             }
  6163.             pPrev = pEntry;
  6164.             pEntry = pEntry->m_pNext;
  6165.         }
  6166.     }
  6167.     ::LeaveCriticalSection(&pM->m_csWindowCreate);
  6168.     return pv;
  6169. }
  6170.  
  6171. #if !defined(_WIN32_WCE)
  6172. /////////////////////////////////////////////////////////////////////////////
  6173. // General DLL Version Helpers
  6174.  
  6175. inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
  6176. {
  6177.     ATLASSERT(pDllVersionInfo != NULL);
  6178.     if(::IsBadWritePtr(pDllVersionInfo, sizeof(DWORD)))
  6179.         return E_INVALIDARG;
  6180.  
  6181.     // We must get this function explicitly because some DLLs don't implement it.
  6182.     DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
  6183.     if(pfnDllGetVersion == NULL)
  6184.         return E_NOTIMPL;
  6185.  
  6186.     return (*pfnDllGetVersion)(pDllVersionInfo);
  6187. }
  6188.  
  6189. inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
  6190. {
  6191.     HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
  6192.     if(hInstDLL == NULL)
  6193.         return E_FAIL;
  6194.     HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
  6195.     ::FreeLibrary(hInstDLL);
  6196.     return hRet;
  6197. }
  6198.  
  6199. // Common Control Versions:
  6200. //   Win95/WinNT 4.0    maj=4 min=00
  6201. //   IE 3.x        maj=4 min=70
  6202. //   IE 4.0        maj=4 min=71
  6203. inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  6204. {
  6205.     ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
  6206.     if(::IsBadWritePtr(pdwMajor, sizeof(DWORD)) || ::IsBadWritePtr(pdwMinor, sizeof(DWORD)))
  6207.         return E_INVALIDARG;
  6208.  
  6209.     DLLVERSIONINFO dvi;
  6210.     ::ZeroMemory(&dvi, sizeof(dvi));
  6211.     dvi.cbSize = sizeof(dvi);
  6212.     HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
  6213.  
  6214.     if(SUCCEEDED(hRet))
  6215.     {
  6216.         *pdwMajor = dvi.dwMajorVersion;
  6217.         *pdwMinor = dvi.dwMinorVersion;
  6218.     }
  6219.     else if(hRet == E_NOTIMPL)
  6220.     {
  6221.         // If DllGetVersion is not there, then the DLL is a version 
  6222.         // previous to the one shipped with IE 3.x
  6223.         *pdwMajor = 4;
  6224.         *pdwMinor = 0;
  6225.         hRet = S_OK;
  6226.     }
  6227.  
  6228.     return hRet;
  6229. }
  6230.  
  6231. // Shell Versions:
  6232. //   Win95/WinNT 4.0                    maj=4 min=00
  6233. //   IE 3.x, IE 4.0 without Web Integrated Desktop    maj=4 min=00
  6234. //   IE 4.0 with Web Integrated Desktop            maj=4 min=71
  6235. //   IE 4.01 with Web Integrated Desktop        maj=4 min=72
  6236. inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  6237. {
  6238.     ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
  6239.     if(::IsBadWritePtr(pdwMajor, sizeof(DWORD)) || ::IsBadWritePtr(pdwMinor, sizeof(DWORD)))
  6240.         return E_INVALIDARG;
  6241.  
  6242.     DLLVERSIONINFO dvi;
  6243.     ::ZeroMemory(&dvi, sizeof(dvi));
  6244.     dvi.cbSize = sizeof(dvi);
  6245.     HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
  6246.  
  6247.     if(SUCCEEDED(hRet))
  6248.     {
  6249.         *pdwMajor = dvi.dwMajorVersion;
  6250.         *pdwMinor = dvi.dwMinorVersion;
  6251.     }
  6252.     else if(hRet == E_NOTIMPL)
  6253.     {
  6254.         // If DllGetVersion is not there, then the DLL is a version 
  6255.         // previous to the one shipped with IE 4.x
  6256.         *pdwMajor = 4;
  6257.         *pdwMinor = 0;
  6258.         hRet = S_OK;
  6259.     }
  6260.  
  6261.     return hRet;
  6262. }
  6263. #endif // _WIN32_WCE
  6264.  
  6265. #ifndef _ATL_DLL_IMPL
  6266. }; //namespace ATL
  6267. #endif
  6268.  
  6269. //Prevent pulling in second time 
  6270. #undef _ATLBASE_IMPL
  6271.  
  6272. #endif // _ATLBASE_IMPL
  6273.  
  6274. /////////////////////////////////////////////////////////////////////////////
  6275.